The Node.js SDK lets you send events to Amplitude.
Install the dependency with npm or yarn.
1npm install @amplitude/analytics-node
1yarn add @amplitude/analytics-node
Initialization is necessary before you instrument the SDK. The API key for your Amplitude project is required. The SDK can be used anywhere after it's initialized anywhere in an application.
1import { init } from '@amplitude/analytics-node';2 3// Option 1, initialize with API_KEY only4init(API_KEY);5 6// Option 2, initialize including configuration7init(API_KEY, {8 flushIntervalMillis: 30 * 1000, // Sets request interval to 30s9});
Name | Description | Default Value |
---|---|---|
instanceName |
string . The instance name. |
$default_instance |
flushIntervalMillis |
number . Sets the interval of uploading events to Amplitude in milliseconds. |
10,000 (10 seconds) |
flushQueueSize |
number . Sets the maximum number of events that are batched in a single upload attempt. |
300 events |
flushMaxRetries |
number . Sets the maximum number of retries for failed upload attempts. This is only applicable to retryable errors. |
12 times. |
logLevel |
LogLevel.None or LogLevel.Error or LogLevel.Warn or LogLevel.Verbose or LogLevel.Debug . Sets the log level. |
LogLevel.Warn |
loggerProvider |
Logger . Sets a custom loggerProvider class from the Logger to emit log messages to desired destination. |
Amplitude Logger |
minIdLength |
number . Sets the minimum length for the value of user_id and device_id properties. |
5 |
optOut |
boolean . Sets permission to track events. Setting a value of true prevents Amplitude from tracking and uploading events. |
false |
serverUrl |
string . Sets the URL where events are upload to. |
https://api2.amplitude.com/2/httpapi |
serverZone |
EU or US . Sets the Amplitude server zone. Set this to EU for Amplitude projects created in EU data center. |
US |
storageProvider |
Storage<Event[]> . Sets a custom implementation of Storage<Event[]> to persist unsent events. |
MemoryStorage |
transportProvider |
Transport . Sets a custom implementation of Transport to use different request API. |
HTTPTransport |
useBatch |
boolean . Sets whether to upload events to Batch API instead of the default HTTP V2 API or not. |
false |
To support high-performance environments, the SDK sends events in batches. Every event logged by the track
method is queued in memory. Events are flushed in batches in background. You can customize batch behavior with flushQueueSize
and flushIntervalMillis
. By default, the serverUrl will be https://api2.amplitude.com/2/httpapi
. For customers who want to send large batches of data at a time, set useBatch
to true
to set setServerUrl
to batch event upload API https://api2.amplitude.com/batch
. Both the regular mode and the batch mode use the same events upload threshold and flush time intervals.
1import * as amplitude from '@amplitude/analytics-node'; 2 3amplitude.init(API_KEY, { 4 // Events queued in memory will flush when number of events exceed upload threshold 5 // Default value is 30 6 flushQueueSize: 50, 7 // Events queue will flush every certain milliseconds based on setting 8 // Default value is 10000 milliseconds 9 flushIntervalMillis: 20000,10});
You can configure the server zone when initializing the client for sending data to Amplitude's EU servers. The SDK sends data based on the server zone if it's set.
For EU data residency, the project must be set up inside Amplitude EU. You must initialize the SDK with the API key from Amplitude EU.
1import * as amplitude from '@amplitude/analytics-node';23amplitude.init(API_KEY, {4 serverZone: amplitude.Types.ServerZone.EU,5});
You can control the level of logs printed to the developer console.
None
: Suppresses all log messages.Error
: Shows error messages only.Warn
: Shows error messages and warnings. This is the default value if logLevel
isn't explicitly specified.Verbose
: Shows informative messages.Debug
: Shows error messages, warnings, and informative messages that may be useful for debugging, including the function context information for all SDK public method invocations. This logging mode is only suggested to be used in development phases.Set the log level by configuring the logLevel
with the level you want.
1amplitude.init(AMPLITUDE_API_KEY, {2 logLevel: amplitude.Types.LogLevel.Warn,3});
The default logger outputs log to the developer console. You can provide your own logger implementation based on the Logger
interface for any customization purpose. For example, collecting any error messages from the SDK in a production environment.
Set the logger by configuring the loggerProvider
with your own implementation.
1amplitude.init(AMPLITUDE_API_KEY, {2 loggerProvider: new MyLogger(),3});
Enable the debug mode by setting the logLevel
to "Debug", for example:
1amplitude.init(AMPLITUDE_API_KEY, {2 logLevel: amplitude.Types.LogLevel.Debug,3});
With the default logger, extra function context information will be output to the developer console when invoking any SDK public method, including:
type
: Category of this context, for example, invoke public method
.name
: Name of invoked function, for example, setUserId
.args
: Arguments of the invoked function.stacktrace
: Stacktrace of the invoked function.time
: Start and end timestamp of the function invocation.states
: Useful internal states snapshot before and after the function invocation.This SDK uses the HTTP V2 API and follows the same constraints for events. Make sure that all events logged in the SDK have the event_type
field and at least one of deviceId
(included by default) or userId
, and follow the HTTP API's constraints on each of those fields.
To prevent instrumentation issues, device IDs and user IDs must be strings with a length of 5 characters or more. If an event contains a device ID or user ID that's too short, the ID value is removed from the event. If the event doesn't have a userId
or deviceId
value, the upload may be rejected with a 400 status. Override the default minimum length of 5 characters by setting the minIdLength
config option.
Events represent how users interact with your application. For example, "Button Clicked" may be an action you want to note.
1import { track } from '@amplitude/analytics-node'; 2 3// Track a basic event 4track('Button Clicked', undefined, { 5 user_id: 'user@amplitude.com', 6}); 7 8// Track events with optional properties 9const eventProperties = {10 buttonColor: 'primary',11};12track('Button Clicked', eventProperties, {13 user_id: 'user@amplitude.com',14});
If you need to log events to multiple Amplitude projects, you'll need to create separate instances for each Amplitude project. Then, pass the instance variables to wherever you want to call Amplitude. Each instance allows for independent apiKeys, userIds, deviceIds, and settings.
1import * as amplitude from '@amplitude/analytics-node';2 3const defaultInstance = amplitude.createInstance();4defaultInstance.init(API_KEY_DEFAULT);5 6const envInstance = amplitude.createInstance();7envInstance.init(API_KEY_ENV, {8 instanceName: 'env',9});
User properties help you understand your users at the time they performed some action within your app such as their device details, their preferences, or language.
Identify is for setting the user properties of a particular user without sending any event. The SDK supports the operations set
, setOnce
, unset
, add
, append
, prepend
, preInsert
, postInsert
, and remove
on individual user properties. The operations are declared via a provided Identify interface. Chain together multiple operations together in a single Identify object. The Identify object is then passed to the Amplitude client to send to the server.
If the Identify call is sent after the event, the results of operations are visible immediately in the dashboard user's profile area, but it don't appear in chart result until another event is sent after the Identify call. The identify call only affects events going forward. See Overview of user properties and event properties in Amplitude for more information.
The Identify object provides controls over setting user properties. An Identify object must first be instantiated, then Identify methods can be called on it, and finally the client makes a call with the Identify object.
1import { identify, Identify } from '@amplitude/analytics-node';2 3const identifyObj = new Identify();4identify(identifyObj, {5 user_id: 'user@amplitude.com',6});
This method sets the value of a user property. For example, you can set a role property of a user.
1import { Identify, identify } from '@amplitude/analytics-node';2 3const identifyObj = new Identify();4identifyObj.set('location', 'LAX');5 6identify(identifyObj, {7 user_id: 'user@amplitude.com',8});
This method sets the value of a user property only once. Subsequent calls using setOnce()
are ignored. For example, you can set an initial login method for a user and since only the initial value is tracked, setOnce() ignores subsequent calls.
1import { Identify, identify } from '@amplitude/analytics-node';2 3const identifyObj = new Identify();4identifyObj.setOnce('initial-location', 'SFO');5 6identify(identifyObj, {7 user_id: 'user@amplitude.com',8});
This method increments a user property by some numerical value. If the user property doesn't have a value set yet, it's initialized to 0 before being incremented. For example, you can track a user's travel count.
1import { Identify, identify } from '@amplitude/analytics-node';2 3const identifyObj = new Identify();4identifyObj.add('travel-count', 1);5 6identify(identifyObj, {7 user_id: 'user@amplitude.com',8});
Arrays can be used as user properties. You can directly set arrays or use prepend
, append
, preInsert
and postInsert
to generate an array.
This method prepends a value or values to a user property array. If the user property doesn't have a value set yet, it's initialized to an empty list before the new values are prepended.
1import { Identify, identify } from '@amplitude/analytics-node';2 3const identifyObj = new Identify();4identifyObj.prepend('visited-locations', 'LAX');5 6identify(identifyObj, {7 user_id: 'user@amplitude.com',8});
This method appends a value or values to a user property array. If the user property doesn't have a value set yet, it's initialized to an empty list before the new values are prepended.
1import { Identify, identify } from '@amplitude/analytics-node';2 3const identifyObj = new Identify();4identifyObj.append('visited-locations', 'SFO');5 6identify(identifyObj, {7 user_id: 'user@amplitude.com',8});
This method pre-inserts a value or values to a user property if it doesn't exist in the user property yet. Pre-insert means inserting the value at the beginning of a given list. If the user property doesn't have a value set yet, it's initialized to an empty list before the new values are pre-inserted. If the user property has an existing value, it's a no operation.
1import { Identify, identify } from '@amplitude/analytics-node';2 3const identifyObj = new Identify();4identifyObj.preInsert('unique-locations', 'LAX');5 6identify(identifyObj, {7 user_id: 'user@amplitude.com',8});
This method post-inserts a value or values to a user property if it doesn't exist in the user property yet. Post-insert means inserting the value at the end of a given list. If the user property doesn't have a value set yet, it's initialized to an empty list before the new values are post-inserted. If the user property has an existing value, it's a no operation.
1import { Identify, identify } from '@amplitude/analytics-node';2 3const identifyObj = new Identify();4identifyObj.postInsert('unique-locations', 'SFO');5 6identify(identifyObj, {7 user_id: 'user@amplitude.com',8});
This method removes a value or values to a user property if it exists in the user property. Remove means remove the existing value from the given list. If the item doesn't exist in the user property, it's a no operation.
1import { Identify, identify } from '@amplitude/analytics-node';2 3const identifyObj = new Identify();4identifyObj.remove('unique-locations', 'JFK')5 6identify(identifyObj, {7 user_id: 'user@amplitude.com',8});
Amplitude supports assigning users to groups and performing queries, such as Count by Distinct, on those groups. If at least one member of the group has performed the specific event, then the count includes the group.
For example, you want to group your users based on what organization they're in by using an 'orgId'. Joe is in 'orgId' '10', and Sue is in 'orgId' '15'. Sue and Joe both perform a certain event. You can query their organizations in the Event Segmentation Chart.
When setting groups, define a groupType
and groupName
. In the previous example, 'orgId' is the groupType
and '10' and '15' are the values for groupName
. Another example of a groupType
could be 'sport' with groupName
values like 'tennis' and 'baseball'.
Setting a group also sets the groupType:groupName
as a user property, and overwrites any existing groupName
value set for that user's groupType, and the corresponding user property value. groupType
is a string, and groupName
can be either a string or an array of strings to indicate that a user is in multiple groups.
If Joe is in 'orgId' '15', then the groupName
would be '15'.
1import { setGroup } from '@amplitude/analytics-node';2 3// set group with a single group name4setGroup('orgId', '15', {5 user_id: 'user@amplitude.com',6});
If Joe is in 'sport' 'tennis' and 'soccer', then the groupName
would be '["tennis", "soccer"]'.
1import { setGroup } from '@amplitude/analytics-node';2 3// set group with multiple group names4setGroup('sport', ['soccer', 'tennis'], {5 user_id: 'user@amplitude.com',6});
You can also set event-level groups by passing an Event
Object with groups
to track
. With event-level groups, the group designation applies only to the specific event being logged, and doesn't persist on the user unless you explicitly set it with setGroup
.
1import { track } from '@amplitude/analytics-node';2 3track({4 event_type: 'event type',5 event_properties: { eventPropertyKey: 'event property value' },6 groups: { 'orgId': '15' }7}, undefined, {8 user_id: 'user@amplitude.com',9});
Use the Group Identify API to set or update the properties of particular groups. These updates only affect events going forward.
The groupIdentify()
method accepts a group type and group name string parameter, as well as an Identify object that's applied to the group.
1import { Identify, groupIdentify } from '@amplitude/analytics-node'; 2 3const groupType = 'plan'; 4const groupName = 'enterprise'; 5const event = new Identify() 6event.set('key1', 'value1'); 7 8groupIdentify(groupType, groupName, identify, { 9 user_id: 'user@amplitude.com',10});
The preferred method of tracking revenue for a user is to use revenue()
in conjunction with the provided Revenue interface. Revenue instances store each revenue transaction and allow you to define several special revenue properties (such as "revenueType", "productIdentifier", etc.) that are used in Amplitude's Event Segmentation and Revenue LTV charts. These Revenue instance objects are then passed into revenue()
to send as revenue events to Amplitude. This lets automatically display data relevant to revenue in the platform. You can use this to track both in-app and non-in-app purchases.
To track revenue from a user, call revenue each time a user generates revenue. For example, a customer purchased 3 units of a product at $3.99.
1import { Revenue, revenue } from '@amplitude/analytics-node'; 2 3const event = new Revenue() 4 .setProductId('com.company.productId') 5 .setPrice(3.99) 6 .setQuantity(3); 7 8revenue(event, { 9 user_id: 'user@amplitude.com',10});
Name | Description |
---|---|
product_id |
Optional. String. An identifier for the product. Amplitude recommends something like the Google Play Store product ID. Defaults to null. |
quantity |
Required. Int. The quantity of products purchased. Note: revenue = quantity * price. Defaults to 1 |
price |
Required. Double. The price of the products purchased, and this can be negative. Note: revenue = quantity * price. Defaults to null. |
revenue_type |
Optional, but required for revenue verification. String. The revenue type (for example, tax, refund, income). Defaults to null. |
receipt |
Optional. String. The receipt identifier of the revenue. Defaults to null |
receipt_sig |
Optional, but required for revenue verification. String. The receipt signature of the revenue. Defaults to null. |
properties |
Optional. JSONObject. An object of event properties to include in the revenue event. Defaults to null. |
The flush
method triggers the client to send buffered events.
1import { flush } from '@amplitude/analytics-node';2 3flush();
By default, flush
is called automatically in an interval, if you want to flush the events altogether, you can control the async flow with the optional Promise interface, for example:
1await init(AMPLITUDE_API_KEY).promise;2track('Button Clicked', undefined, {3 user_id: 'user@amplitude.com',4});5await flush().promise;
You can turn off logging for a given user by setting setOptOut
to true
.
1import { setOptOut } from '@amplitude/analytics-node';2 3setOptOut(true);
No events are saved or sent to the server while setOptOut
is enabled, and the setting persists across page loads.
Re-enable logging by setting setOptOut
to false
.
1import { setOptOut } from '@amplitude/analytics-node';2 3setOptOut(false);
All asynchronous APIs are optionally awaitable through a Promise interface. This also serves as a callback interface.
1import { track } from '@amplitude/analytics-node'; 2 3// Using async/await 4const results = await track('Button Clicked', undefined, { 5 user_id: 'user@amplitude.com', 6}).promise; 7result.event; // {...} (The final event object sent to Amplitude) 8result.code; // 200 (The HTTP response status code of the request. 9result.message; // "Event tracked successfully" (The response message)10 11// Using promises12track('Button Clicked', undefined, {13 user_id: 'user@amplitude.com',14}).promise.then((result) => {15 result.event; // {...} (The final event object sent to Amplitude)16 result.code; // 200 (The HTTP response status code of the request.17 result.message; // "Event tracked successfully" (The response message)18});
Plugins allow you to extend Amplitude SDK's behavior by, for example, modifying event properties (enrichment type) or sending to third-party APIs (destination type). A plugin is an object with methods setup()
and execute()
.
The add
method adds a plugin to Amplitude client instance. Plugins can help processing and sending events.
1import { add } from '@amplitude/analytics-node';2 3add(new Plugin());
The remove
method removes the given plugin name from the client instance if it exists.
1import { remove } from '@amplitude/analytics-node';2 3remove(plugin.name);
Field / Function | Description |
---|---|
plugin.setup() |
Optional. The setup function is an optional method called when you add the plugin or on first init whichever happens later. This function accepts two parameters: 1) Amplitude configuration; and 2) Amplitude instance. This is useful for setup operations and tasks that depend on either the Amplitude configuration or instance. Examples include assigning baseline values to variables, setting up event listeners, and many more. |
plugin.execute() |
Optional for type:enrichment. For enrichment plugins, execute function is an optional method called on each event. This function must return a new event, otherwise, the SDK drops the passed event from the queue. This is useful for cases where you need to add/remove properties from events, filter events, or perform any operation for each event tracked. For destination plugins, execute function is a required method called on each event. This function must return a response object with keys: event (BaseEvent), code (number), and message (string). This is useful for sending events for third-party endpoints. |
event_id
property of an event starting from 100.
1import { init, add } from '@amplitude/analytics-node'; 2import { NodeConfig, EnrichmentPlugin, Event, PluginType } from '@amplitude/analytics-types'; 3 4export class AddEventIdPlugin implements EnrichmentPlugin { 5 name = 'add-event-id'; 6 type = PluginType.ENRICHMENT as const; 7 currentId = 100; 8 config?: NodeConfig; 9 10 /**11 * setup() is called on plugin installation12 * example: client.add(new AddEventIdPlugin());13 */14 async setup(config: NodeConfig): Promise<undefined> {15 this.config = config;16 return;17 }18 19 /**20 * execute() is called on each event instrumented21 * example: client.track('New Event');22 */23 async execute(event: Event): Promise<Event> {24 event.event_id = this.currentId++;25 return event;26 }27}28 29init('API_KEY');30add(new AddEventIdPlugin());
1import { init, add } from '@amplitude/analytics-node'; 2import { NodeConfig, DestinationPlugin, Event, PluginType, Result } from '@amplitude/analytics-types'; 3import fetch from 'node-fetch'; 4 5export class MyDestinationPlugin implements DestinationPlugin { 6 name = 'my-destination-plugin'; 7 type = PluginType.DESTINATION as const; 8 serverUrl: string; 9 config?: NodeConfig;10 11 constructor(serverUrl: string) {12 this.serverUrl = serverUrl;13 }14 15 /**16 * setup() is called on plugin installation17 * example: client.add(new MyDestinationPlugin());18 */19 async setup(config: NodeConfig): Promise<undefined> {20 this.config = config;21 return;22 }23 24 /**25 * execute() is called on each event instrumented26 * example: client.track('New Event');27 */28 async execute(event: Event): Promise<Result> {29 const payload = { key: 'secret', data: event };30 const response = await fetch(this.serverUrl, {31 method: 'POST',32 headers: {33 'Content-Type': 'application/json',34 Accept: '*/*',35 },36 body: JSON.stringify(payload),37 });38 return {39 code: response.status,40 event: event,41 message: response.statusText,42 };43 }44}45 46init('API_KEY');47add(new MyDestinationPlugin('https://custom.domain.com'));
You can provide an implementation of Transport
interface to the transportProvider
configuration option for customization purpose, for example, sending requests to your proxy server with customized HTTP request headers.
1import { Transport } from '@amplitude/analytics-types'; 2 3class MyTransport implements Transport { 4 async send(serverUrl: string, payload: Payload): Promise<Response | null> { 5 // check example: https://github.com/amplitude/Amplitude-TypeScript/blob/main/packages/analytics-client-common/src/transports/fetch.ts 6 } 7} 8 9amplitude.init(API_KEY, {10 transportProvider: new MyTransport(),11});
Thanks for your feedback!
July 23rd, 2024
Need help? Contact Support
Visit Amplitude.com
Have a look at the Amplitude Blog
Learn more at Amplitude Academy
© 2024 Amplitude, Inc. All rights reserved. Amplitude is a registered trademark of Amplitude, Inc.