NAV Navigation

Introduction

Welcome to Amplitude's developer documentation. This guide will show you how to start instrumenting your application with Amplitude.

How Amplitude Works

To understand how Amplitude works, let’s walk through a hypothetical example.

Tunes is a standard music player for mobile devices that has common actions like playing a song, skipping a song, shuffling play, and sharing a song.

Using Amplitude, you can track all the actions your users make in detail and better understand what’s working and what’s not.

What actions will Amplitude keep track of?

Amplitude gives you the power to determine what’s important to your experience. You can choose to track anything and everything.

For example, in Tunes, you could track the music control buttons the users presses or even how many songs each user has listened to in each session.

Events represent actions users have taken

Every time an action happens that you wish to keep track of, you send an Event to Amplitude. Events can be as easy as choosing the text string that defines them.
For example, in Tunes, you could send an “Play Song” event every time a user presses the Play button.

amplitude.getInstance().logEvent(‘play song’);
[[Amplitude instance] logEvent:@"play song"];
Amplitude.getInstance().logEvent("play song");
Amplitude.Instance.logEvent("play song");




Here is a chart with the number of songs played on each day:

Event Properties provide context

Event Properties give you context about events, like where in your app they occur or what state the app is in when it occurred.
For example, in Tunes, when someone presses the “Play Song” event, using an Event property, you could also track the title of the song being played, the artist, the genre, etc. Any detail related to the Event itself is can act as an event property.

amplitude.getInstance().logEvent(‘play song’,
    { title: ‘Here comes the Sun’,
      artist: ‘The Beatles’, genre: ‘Rock’});
NSMutableDictionary *songProperties = [NSMutableDictionary dictionary];
[eventProperties setValue:@"title" forKey:@"Here comes the Sun"];
[eventProperties setValue:@"artist" forKey:@"The Beatles"];
[eventProperties setValue:@"genre" forKey:@"Rock"];
[[Amplitude instance] logEvent:@"play song" withEventProperties:songProperties];
JSONObject songProperties = new JSONObject();
try {
    eventProperties.put("title", "Here comes the Sun");
    eventProperties.put("artist", "The Beatles");
    eventProperties.put("genre", "Rock");
} catch (JSONException exception) {
}
Amplitude.getInstance().logEvent("play song", eventProperties);
Dictionary<string, object> songProperties = new Dictionary<string, object>() {
  {"title" , "Here comes the Sun" },
  {"artist" , "The Beatles"},
  {"genre" , "Rock"}
};
Amplitude.Instance.logEvent("play song", songProperties);





Here is a chart with the songs played per day in each genre:

User Sessions are a series of Events within a single visit

User Sessions allow you to track series of events that are performed within a single visit or interaction with your application.

Most often, Amplitude keeps track of session automatically for you. If you are using the HTTP API, you will need to handle sessions manually.

User Properties are details about your User

User Properties help understand your User at the time they performed actions within your application. What state they were in, their preferences, or their device details, are all examples of common user properties.

For example, in Tunes, you could keep track of whether or not a User was on a paid or free plan. This will allow you to segment these users by this property, and compare paid vs free users (or only consider the behavior of paying users).

var identify = new amplitude.Identify().set('plan', 'premium');
amplitude.getInstance().identify(identify);
Identify identify = new Identify().set("plan", "premium");
Amplitude.getInstance().identify(identify);
Amplitude.Instance.setUserProperty("plan", "premium");
AMPIdentify *identify = [[[AMPIdentify identify] set:@"plan" value:@"premium"]];
[[Amplitude instance] identify:identify];





Here is an example of a chart segmented on the user property "gender":

Setting up our SDKs

To install our SDKs, you will first need an Amplitude Account. If you have not already, go here and register for an account. Then, create an organization and a project. You will immediately receive an API Key for the project you have just created.

Then choose your platform to the right.

Installation

<script type="text/javascript">
  (function(e,t){var n=e.amplitude||{_q:[],_iq:{}};var r=t.createElement("script")
  ;r.type="text/javascript";r.async=true
  ;r.src="https://cdn.amplitude.com/libs/amplitude-4.2.1-min.gz.js"
  ;r.onload=function(){if(e.amplitude.runQueuedFunctions){
  e.amplitude.runQueuedFunctions()}else{
  console.log("[Amplitude] Error: could not load SDK")}}
  ;var i=t.getElementsByTagName("script")[0];i.parentNode.insertBefore(r,i)
  ;function s(e,t){e.prototype[t]=function(){
  this._q.push([t].concat(Array.prototype.slice.call(arguments,0)));return this}}
  var o=function(){this._q=[];return this}
  ;var a=["add","append","clearAll","prepend","set","setOnce","unset"]
  ;for(var u=0;u<a.length;u++){s(o,a[u])}n.Identify=o;var c=function(){this._q=[]
  ;return this}
  ;var l=["setProductId","setQuantity","setPrice","setRevenueType","setEventProperties"]
  ;for(var p=0;p<l.length;p++){s(c,l[p])}n.Revenue=c
  ;var d=["init","logEvent","logRevenue","setUserId","setUserProperties","setOptOut",
  "setVersionName","setDomain","setDeviceId","setGlobalUserProperties","identify",
  "clearUserProperties","setGroup","logRevenueV2","regenerateDeviceId","logEventWithTimestamp",
  "logEventWithGroups","setSessionId","resetSessionId"]
  ;function v(e){function t(t){e[t]=function(){
  e._q.push([t].concat(Array.prototype.slice.call(arguments,0)))}}
  for(var n=0;n<d.length;n++){t(d[n])}}v(n);n.getInstance=function(e){
  e=(!e||e.length===0?"$default_instance":e).toLowerCase()
  ;if(!n._iq.hasOwnProperty(e)){n._iq[e]={_q:[]};v(n._iq[e])}return n._iq[e]}
  ;e.amplitude=n})(window,document);

  amplitude.getInstance().init("{API_KEY}");
</script>






























npm install amplitude-js




bower install amplitude-js






#import "Amplitude.h"



[[Amplitude instance] initializeApiKey:@"{API_KEY}"];



<uses-permission android:name="android.permission.INTERNET" />





import com.amplitude.api.Amplitude;





Amplitude.getInstance().initialize(this, "{API_KEY}")
    .enableForegroundTracking(getApplication());




Note: if your app has multiple entry points/exit points, you should make a Amplitude.getInstance().initialize() at every onCreate() entry point.

    -keep class com.google.android.gms.ads.** { *; }
    -dontwarn okio.**




NOTE: by default unsent events are uploaded when your app is minimized or closed via the Activity Lifecycle onPause callback. If you wish to disable this behavior you can call:

Amplitude.getInstance().setFlushEventsOnClose(false);
void Awake () {
  Amplitude amplitude = Amplitude.Instance;
  amplitude.logging = true;
  amplitude.init("{API_KEY}");
}







For information on setting up Amplitude for this platform, look at the HTTP API Section

Setting up Segment

segment

SDK Basics

Tracking Events

It is important to consider what types of events you care about as a developer. You should aim to track between 20 and 200 types of events on your site. Common event types are actions the user initiates (such as pressing a button) and events you want the user to complete (such as filling out a form, completing a level, or making a payment).

Here are some resources to help you with your taxonomy or instrumentation planning:

Having a large number of distinct event types, event properties, and user properties can make data exploration and visualization very confusing. By default, we only show the first:

Anything past the above thresholds will not be visualized. Note: The raw data is not impacted by this in any way, meaning that you will still see the values in the raw data but they will not be visualized in the platform. A single call to logEvent should not have more than 1000 event properties. Likewise, a single call to setUserProperties should not have more than 1000 user properties. If the 1000 property limit is exceeded then the properties will be dropped and a warning will be printed in the console. We have put in very conservative estimates for the event type and property caps that we do not expect to be exceeded in any practical use case. If you feel that your use case will go above those limits please reach out to us here.

You will have to explicitly log events in order to see data in your project. To track an event from anywhere in the app, call:

Amplitude.getInstance().logEvent("EVENT_TYPE");
Amplitude.Instance.logEvent("EVENT_TYPE");
[[Amplitude instance] logEvent:@"EVENT_TYPE"];
amplitude.getInstance().logEvent('EVENT_TYPE');
curl --data 'api_key={API_KEY}'
  --data-urlencode 'event=[{"user_id":"datamonster@gmail.com",
                            "event_type":"watch_tutorial",
                            "user_properties":{"Cohort":"Test A"},
                            "country":"United States", "ip":"127.0.0.1",
                            "time":1396381378123}]' https://api.amplitude.com/httpapi




the appropriate REST call

Events are saved locally. For our mobile SDKs, uploads are batched to occur every 30 events and every 30 seconds. When a user is offline, we store their most recent 1000 events by default and then upload them once the user is online again. When the user returns online, their events are processed by first in, first out. If you want to change the frequency at which events are uploaded, you can do this by using setEventUploadThreshold.

Logging Events to a Single Project

If you want to log events to a single Amplitude project (and a single API key), then you should call functions on the default instance. You can fetch this by calling amplitude.getInstance() with no instance name. Here is an example:

amplitude.getInstance().init('API_KEY');
amplitude.getInstance().logEvent('EVENT_TYPE');





You can also assign instances to a variable and call functions on that variable:

var project = amplitude.getInstance();
project.init('API_KEY');
project.logEvent('EVENT_TYPE');




Logging Events to Multiple Projects

If you want to log events to multiple Amplitude projects, then you will need to have separate instances for each Amplitude project. As mentioned earlier, each instance will allow for completely independent apiKeys, userIds, deviceIds, and settings.

You will need to assign a name to each Amplitude project/instance and use that name consistently when fetching that instance to call functions.

IMPORTANT NOTE: Once you have chosen a name for that instance you cannot change it.

Choose your instance names wisely because every instance's data and settings are tied to its name, and you will need to continue using that instance name for all future versions of your project to maintain data continuity. These names do not need to be the names of your projects in the Amplitude platform, but they will need to remain consistent throughout your code. You also need to be sure that each instance is initialized with the correct apiKey.

Instance names must be non-null and non-empty strings. Names are case insensitive, and you can fetch each instance name by calling

amplitude.getInstance('INSTANCE_NAME')
[Amplitude instanceWithName:@"INSTANCE_NAME"]



As mentioned before, each new instance created will have its own apiKey, userId, deviceId, and settings. IMPORTANT NOTE: You will have to reconfigure all the settings for each instance. This gives you the freedom to have different settings for each instance.

The following is an example of how to set up and log events to two separate projects:

// existing project, existing settings, and existing API key
amplitude.getInstance().init('12345', null, {batchEvents: true});
// new project, new API key
amplitude.getInstance('new_project').init('67890', null, {includeReferrer: true});

// need to reconfigure new project
amplitude.getInstance('new_project').setUserId('joe@gmail.com');
amplitude.getInstance('new_project').setUserProperties({'gender':'male'});
amplitude.getInstance('new_project').logEvent('Clicked');

var identify = new amplitude.Identify().add('karma', 1);
amplitude.getInstance().identify(identify);
amplitude.getInstance().logEvent('Viewed Home Page');
// existing project, existing settings, and existing API key
[[Amplitude instance] initializeApiKey:@"12345"];
[[Amplitude instanceWithName:@"new_project"] initializeApiKey:@"67890"]; // new project, new API key

[[Amplitude instanceWithName:@"new_project"] setUserId:@"joe@gmail.com"]; // need to reconfigure new project
[[Amplitude instanceWithName:@"new_project"] logEvent:@"Clicked"];

AMPIdentify *identify = [[AMPIdentify identify] add:@"karma" value:[NSNumber numberWithInt:1]];
[[Amplitude instance] identify:identify];
[[Amplitude instance] logEvent:@"Viewed Home Page"];















Synchronizing device IDs between apps

As mentioned before, each instance will have its own deviceId. If you want your projects to share the same deviceId, you can do so after init by fetching the deviceId and using setDeviceId. Here is an example of how to copy the existing deviceId to the new_project instance:

// existing deviceId
var deviceId = amplitude.getInstance().options.deviceId;
// transferring existing deviceId to new_project
amplitude.getInstance('new_project').setDeviceId(deviceId);
// existing deviceId
NSString *deviceId = [[Amplitude instance] getDeviceId];
// transferring existing deviceId to new project
[[Amplitude instanceWithName:@"new_project"] setDeviceId:deviceId];





Tracking Sessions

Events triggered within 30 minutes of each other are counted towards the current session. The time of the first event marks the start time of a session and the last event triggered marks the end time of a session. You can change the session timeout window via the [SDK configuration option] sessionTimeout.

A session is a period of time that a user has the app in the foreground. Events that are logged within the same session will have the same session_id. Sessions are handled automatically so you do not have to manually call startSession() or endSession().

For Android API level 14 and above, a new session is created when the app comes back into the foreground after being in the background for five or more minutes or when the last event was logged (whichever occurred last). Otherwise, the background event logged will be part of the current session. Note that you can define your own session expiration time by calling setMinTimeBetweenSessionsMillis(timeout), where the timeout input is in milliseconds.

For Android API level 13 and below, foreground tracking is not available so a new session is automatically started when an event is logged 30 minutes or more after the last logged event. If another event is logged within 30 minutes, it will extend the current session. Note that you can define your own session expiration time here as well by calling setSessionTimeoutMillis(timeout), where the timeout input is in milliseconds. Also note that enableForegroundTracking(getApplication) is still safe to call for Android API level 13 and below even though it is not available.

You can adjust the time window for which sessions are extended by changing the variable minTimeBetweenSessionsMillis:

[Amplitude instance].minTimeBetweenSessionsMillis = 30 * 60 * 1000; // 30 minutes
[[Amplitude instance] initializeApiKey:@"API_KEY"];

By default, '[Amplitude] Start Session' and '[Amplitude] End Session' events are no longer sent. Even though these events are not sent, sessions are still tracked by using session_id. To re-enable those session events, add this line before initializing the SDK:

Amplitude.getInstance().trackSessionEvents(true);
Amplitude amplitude = Amplitude.Instance;
amplitude.trackSessionEvents(true);
amplitude.init("API_KEY");
[[Amplitude instance] setTrackingSessionEvents:YES];
[[Amplitude instance] initializeApiKey:@"API_KEY"];






You can also log events as out-of-session. Out-of-session events have a session_id of -1 and are not considered part of the current session, meaning they do not extend the current session. This might be useful if you are logging events triggered by push notifications, for example. You can log events as out-of-session by setting the input parameter outOfSession to true when calling logEvent():

Amplitude.getInstance().logEvent("EVENT_TYPE", null, true);
[[Amplitude instance] logEvent:@"EVENT_TYPE" withEventProperties:nil outOfSession:YES];




You can also log identify events as out-of-session, which is useful if you are updating user properties in the background and do not want to start a new session. You can do this by setting the input parameter outOfSession to true when calling identify():

Identify identify = new Identify().set("key", "value");
Amplitude.getInstance().identify(identify, true);
AMPIdentify *identify = [[AMPIdentify identify] set:@"key" value:@"value"];
[[Amplitude instance] identify:identify outOfSession:YES];





Getting the Session ID

You can use the helper method _sessionId to get the value of the current sessionId:

var sessionId = amplitude.getInstance()._sessionId;

You can use the helper method getSessionId to get the value of the current sessionId:

long sessionId = Amplitude.getInstance().getSessionId();
long long sessionId = [[Amplitude instance] getSessionId];

Setting Custom User IDs

If your app has its own login system that you want to track users with, you can call setUserId at any time:

amplitude.getInstance().setUserId('USER_ID');
Amplitude.getInstance().setUserId("USER_ID");
Amplitude.Instance.setUserId("USER_ID");
[[Amplitude] instance] setUserId:@"USER_ID"];

You can also add the User ID as an argument to the init call:

amplitude.getInstance().init('API_KEY', 'USER_ID');
Amplitude.getInstance().initialize(this, "API_KEY", "USER_ID");
Amplitude.Instance.init("API_KEY", "USER_ID");
[[Amplitude] instance] initializeApiKey:@"API_KEY" userId:@"USER_ID"];

You should not assign users a User ID that could change as each unique User ID is interpreted as a unique user in Amplitude. Please see our article on how we identify and count unique users for further information.

Logging Out and Anonymous Users

A user's data will be merged on the backend so that any events up to that point from the same browser will be tracked under the same user. If a user logs out or you want to log the events under an anonymous user, you will need to:

  1. Set the userId to null.
  2. Regenerate a new deviceId.

After doing that, events coming from the current user/device will appear as a brand new user in Amplitude. Note: If you choose to do this, you will not be able to see that the two users were using the same device. Here is an example:

amplitude.getInstance().setUserId(null); // not string 'null'
amplitude.getInstance().regenerateDeviceId();
Amplitude.getInstance().setUserId(null);
Amplitude.getInstance().regenerateDeviceId();
[[Amplitude instance] setUserId:nil]; // not string nil
[[Amplitude instance] regenerateDeviceId];

Setting Event Properties

You can send event property attributes to any event by passing a JavaScript object as the second argument to logEvent. The JavaScript object should be in the form of key + value pairs that can be JSON serialized. The keys should be strings but the values can be booleans, strings, numbers, arrays of strings/numbers/booleans, nested JavaScript objects, or errors (note that you cannot nest arrays or JavaScript objects inside array values). The SDK will validate the event properties that you set and will log any errors or warnings to console if there are any issues. Here is an example:

var eventProperties = {};
eventProperties.key = 'value';
amplitude.getInstance().logEvent('EVENT_TYPE', eventProperties);




Alternatively, you can set multiple event properties like this:

var eventProperties = {
 'color': 'blue',
 'age': 20,
 'key': 'value'
};
amplitude.getInstance().logEvent('EVENT_TYPE', eventProperties);







You can send event property attributes to any event by passing a JSONObject as the second argument to logEvent():

JSONObject eventProperties = new JSONObject();
try {
    eventProperties.put("KEY", "VALUE");
} catch (JSONException exception) {
}
Amplitude.getInstance().logEvent("Sent Message", eventProperties);
Dictionary<string, object> demoOptions = new Dictionary<string, object>() {
  {"Bucket" , "A" },
  {"Credits" , 9001}
};
Amplitude.Instance.logEvent("Sent Message", demoOptions);







You will need to add two JSONObject imports to the code:

import org.json.JSONException;
import org.json.JSONObject;




You can send event property attributes to any event by passing a NSDictionary object as the second argument to logEvent:withEventProperties:

NSMutableDictionary *eventProperties = [NSMutableDictionary dictionary];
[eventProperties setValue:@"VALUE" forKey:@"KEY"];
[[Amplitude instance] logEvent:@"Compute Hash" withEventProperties:eventProperties];





Note: The keys should be of type NSString and the values should be of type NSString, NSNumber, NSArray, NSDictionary, or NSNull. You will see a warning if you try to use an unsupported type.

Arrays in Event Properties

The SDK supports arrays in event properties. Here is an example:

var colors = ['rose', 'gold'];
var eventProperties = {'colors': colors};
amplitude.getInstance().logEvent('Purchase iPhone', eventProperties);
JSONArray colors = new JSONArray();
colors.put("rose").put("gold");
JSONObject eventProperties = new JSONObject();
eventProperties.put("colors", colors);
Amplitude.getInstance().logEvent("Purchased iPhone", colors);
NSMutableArray *colors = [NSMutableArray array];
[colors addObject:@"rose"];
[colors addObject:@"gold"];
NSMutableDictionary *eventProperties = [NSMutableDictionary dictionary];
[eventProperties setObject:colors forKey:@"colors"];
[[Amplitude instance] logEvent:@"Purchase iPhone" withEventProperties:eventProperties];







Setting User Properties

IMPORTANT NOTE: Please be sure to not track any user data that may be against your privacy terms. If you need any assistance with privacy concerns, then please reach out to our Platform team here.

The SDK automatically pulls useful data about the browser, including browser type and operating system version. They are displayed as user properties in Amplitude. You can read more about them here.

The SDK supports the operations set, setOnce, unset, and add on individual user properties. The operations are declared via a provided Identify interface. Multiple operations can be chained together in a single Identify object. The Identify object is then passed to the Amplitude client to send to the server. The results of the operations will be visible immediately in the dashboard and will take effect for events logged after.

To use the Identify interface, you will first need to import the class:

To use the AMPIdentify interface, you will first need to include the header:

import com.amplitude.api.Identify;
#import "AMPIdentify.h"



var identify = new amplitude.Identify().set('gender', 'female').set('age', 20);
amplitude.getInstance().identify(identify);
Identify identify = new Identify().set("gender", "female").set("age", 20);
Amplitude.getInstance().identify(identify);
Amplitude.Instance.setUserProperty("gender", "female"); // string value
Amplitude.Instance.setUserProperty("age", 20); // int value
Amplitude.Instance.setUserProperty("some float values", new float[]{20f, 15.3f, 4.8f}); // float array
AMPIdentify *identify = [[[AMPIdentify identify] set:@"gender" value:@"female"] set:@"age"
    value:[NSNumber numberForInt:20]];
[[Amplitude instance] identify:identify];




var identify = new amplitude.Identify().setOnce('sign_up_date', '2015-08-24');
amplitude.getInstance().identify(identify);

var identify = new amplitude.Identify().setOnce('sign_up_date', '2015-09-14');
amplitude.getInstance().identify(identify);
Identify identify1 = new Identify().setOnce("sign_up_date", "2015-08-24");
Amplitude.getInstance().identify(identify1);

Identify identify2 = new Identify().setOnce("sign_up_date", "2015-09-14");
amplitude.identify(identify2);
Amplitude.Instance.setOnceUserProperty("sign_up_date", "08/24/2015");
Amplitude.Instance.setOnceUserProperty("sign_up_date", "09/14/2015");
AMPIdentify *identify1 = [[AMPIdentify identify] setOnce:@"sign_up_date" value:@"2015-08-24"];
[[Amplitude instance] identify:identify1];

AMPIdentify *identify2 = [[AMPIdentify identify] setOnce:@"sign_up_date" value:@"2015-09-14"];
[[Amplitude instance] identify:identify2];






var identify = new amplitude.Identify().unset('gender').unset('age');
amplitude.getInstance().identify(identify);
Identify identify = new Identify().unset("gender").unset("age");
Amplitude.getInstance().identify(identify);
Amplitude.Instance.unsetUserProperty("sign_up_date");
Amplitude.Instance.unsetUserProperty("age");
AMPIdentify *identify = [[[AMPIdentify identify] unset:@"gender"] unset:@"age"];
[[Amplitude instance] identify:identify];




var identify = new amplitude.Identify().add('karma', 1).add('friends', 1);
amplitude.getInstance().identify(identify);
Identify identify = new Identify().add("karma", 1).add("friends", 1);
Amplitude.getInstance().identify(identify);
Amplitude.Instance.addUserProperty("karma", 1.5);
Amplitude.Instance.addUserProperty("friends", 1);
AMPIdentify *identify = [[[AMPIdentify identify] add:@"karma" value:[NSNumber numberWithFloat:0.123]]
    add:@"friends" value:[NSNumber numberWithInt:1]];
[[Amplitude instance] identify:identify];




var identify = new amplitude.Identify().append('ab-tests', 'new-user-test').append('some_list', [1, 2, 3, 4, 'values']);
amplitude.getInstance().identify(identify);
Identify identify = new Identify().append("ab-tests", "new-user-test")
  .append("some_list", new JSONArray().put(1).put("some_string"));
Amplitude.getInstance().identify(identify);
Amplitude.Instance.appendUserProperty("ab-tests", "new_user_tests");
Amplitude.Instance.appendUserProperty("some_list", new int[]{1, 2, 3, 4});
NSMutableArray *array = [NSMutableArray array];
[array addObject:@"some_string"];
[array addObject:[NSNumber numberWithInt:56]];
AMPIdentify *identify = [[[AMPIdentify identify] append:@"ab-tests" value:@"new-user-test"]
    append:@"some_list" value:array];
[[Amplitude instance] identify:identify];






var identify = new amplitude.Identify().prepend('ab-tests', 'new-user-test').prepend('some_list', [1, 2, 3, 4, 'values']);
amplitude.getInstance().identify(identify);
Identify identify = new Identify().prepend("ab-tests", "new-user-test")
  .prepend("some_list", new JSONArray().put(1).put("some_string"));
Amplitude.getInstance().identify(identify);
NSMutableArray *array = [NSMutableArray array];
[array addObject:@"some_string"];
[array addObject:[NSNumber numberWithInt:56]];
AMPIdentify *identify = [[[AMPIdentify identify] append:@"ab-tests" value:@"new-user-test"]
    prepend:@"some_list" value:array];
[[Amplitude instance] identify:identify];






Note: If a user property is used in multiple operations on the same Identify object, then only the first operation will be saved and the rest will be ignored. In this example, only the set operation will be saved and the add and the unset will be ignored:

var identify = new amplitude.Identify()
 .set('karma', 10)
 .add('karma', 1)
 .unset('karma');
amplitude.getInstance().identify(identify);
Identify identify = new Identify().set("karma", 10).add("karma", 1).unset("karma");
Amplitude.getInstance().identify(identify);
AMPIdentify *identify = [[[[AMPIdentify identify] set:@"karma" value:[NSNumber numberWithInt:10]]
    add:@"friends" value:[NSNumber numberWithInt:1]] unset:@"karma"];
    [[Amplitude instance] identify:identify];




Arrays in User Properties

The SDK supports arrays in user properties. Any of the user property operations above (with the exception of add) can accept a JSONArray. You can directly set arrays or use append to generate an array.

var identify = new amplitude.Identify()
    .set('colors', ['rose', 'gold'])
    .append('ab-tests', 'campaign_a')
    .append('existing_list', [4, 5]);
amplitude.getInstance().identify(identify);
JSONArray colors = new JSONArray();
colors.put("rose").put("gold");
Identify identify = new Identify().set("colors", colors)
  .append("ab-tests", "campaign_a").append("existing_list", new int[]{4,5});
Amplitude.getInstance().identify(identify);
List<double> list = new List<double>();
list.add(2.5);
list.add(6.8);
Amplitude.Instance.appendUserProperty("my_list", list);
NSMutableArray *colors = [NSMutableArray array];
[colors addObject:@"rose"];
[colors addObject:@"gold"];
NSMutableArray *numbers = [NSMutableArray array];
[numbers addObject:[NSNumber numberWithInt:4]];
[numbers addObject:[NSNumber numberWithInt:5]];
AMPIdentify *identify = [[[[AMPIdentify identify] set:@"colors" value:colors] append:@"ab-tests"
    value:@"campaign_a"] append:@"existing_list" value:numbers];
[[Amplitude instance] identify:identify];






Setting Multiple User Properties

You may use setUserProperties shorthand to set multiple user properties at once. This method is simply a wrapper around Identify.set and identify. Here is an example:

var userProperties = {
 gender: 'female',
 age: 20
};
amplitude.getInstance().setUserProperties(userProperties);
JSONObject userProperties = new JSONObject();
try {
    userProperties.put("KEY", "VALUE");
    userProperties.put("OTHER_KEY", "OTHER_VALUE");
} catch (JSONException exception) {
}
Amplitude.getInstance().setUserProperties(userProperties);
Dictionary<string, object> userProperties = new Dictionary<string, object>() {
  {"float_gprop", 1.0}
};
Amplitude.Instance.setUserProperties(userProperties);
NSMutableDictionary *userProperties = [NSMutableDictionary dictionary];
[userProperties setValue:@"VALUE" forKey:@"KEY"];
[userProperties setValue:@"OTHER_VALUE" forKey:@"OTHER_KEY"];
[[Amplitude instance] setUserProperties:userProperties];




Clearing User Properties

You may use clearUserProperties to clear all user properties at once. This will wipe all of the current user's user properties. Note: The result is irreversible! Amplitude will not be able to sync the user's user property values before the wipe to any future events that the user triggers as they will have been reset.

amplitude.getInstance().clearUserProperties();
Amplitude.getInstance().clearUserProperties();
Amplitude.Instance.clearUserProperties();
[[Amplitude instance] clearUserProperties];



Updating User Properties in the Background

When you are updating user properties in the background and do not wish to trigger a session while updating them, make sure to set outOfSession to true:

Identify identify = new Identify().set("color", "blue");
Amplitude.getInstance().identify(identify, true);
AMPIdentify *identify = [[[AMPIdentify identify] set:@"gender" value:@"female"] set:@"age"
    value:[NSNumber numberForInt:20]];
[[Amplitude instance] identify:identify outOfSession:YES];

Tracking Revenue

The preferred method of tracking revenue for a user now is to use logRevenueV2() in conjunction with the provided Revenue interface. Revenue instances will 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. You can also add event properties to revenue events via the eventProperties field. These Revenue instance objects are then passed into logRevenueV2 to send as revenue events to Amplitude. This allows us to 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 logRevenue() each time a user generates revenue. Here is an example:

Amplitude.Instance.logRevenue("com.company.productid", 1, 3.99);

Calling logRevenueV2 will generate up to 2 different event types in the platform:

You cannot change the default names given to these client-side revenue events in the raw data but you do have the option to modify the display name. To learn more about tracking revenue, see our documentation here.

IMPORTANT NOTE: Amplitude currently does not support currency conversion. All revenue data should be normalized to your currency of choice, before being sent to Amplitude.

To use the Revenue interface, you will first need to import the class:

import com.amplitude.api.Revenue;
#import "AMPRevenue.h"




Each time a user generates revenue, you will need to create an Revenue object and fill out the revenue properties:

Revenue revenue = new Revenue().setProductId("com.company.productId").setPrice(3.99).setQuantity(3);
Amplitude.getInstance().logRevenueV2(revenue);
var revenue = new amplitude.Revenue().setProductId('com.company.productId').setPrice(3.99).setQuantity(3);
amplitude.getInstance().logRevenueV2(revenue);
AMPRevenue *revenue = [[[AMPRevenue revenue] setProductIdentifier:@"productIdentifier"] setQuantity:3];
[revenue setPrice:[NSNumber numberWithDouble:3.99]];
[[Amplitude instance] logRevenueV2:revenue];




Each revenue event has fields available, and each field has a corresponding set method (for example, setProductId, setQuantity, etc.). This table describes the different fields:

Name Type Description Default
productId
optional)
string An identifier for the product. We recommend something like the Google Play Store product ID. null
quantity
(required)
integer The quantity of products purchased. Note: revenue = quantity * price 1
price
(required)
double The price of the products purchased, and this can be negative. Note: revenue = quantity * price null
revenueType
(optional)
string The type of revenue (e.g. tax, refund, income). null
eventProperties
(optional)
object An object of event properties to include in the revenue event. null
Name Type Description Default
productId
optional)
NSString An identifier for the product. We recommend something like the Google Play Store product ID. null
quantity
(required)
NSInteger The quantity of products purchased. Note: revenue = quantity * price 1
price
(required)
NSNumber The price of the products purchased, and this can be negative. Note: revenue = quantity * price null
revenueType
(optional)
NSString The type of revenue (e.g. tax, refund, income). null
receipt
(optional, *required for revenue verification)
NSData This is required if you want to verify the revenue event. null
eventProperties
(optional)
NSDictionary A NSDictionary of event properties to include in the revenue event. null

Note: The price can be negative, which may be useful for tracking revenue lost (e.g. refunds or costs). You can also set event properties on the revenue event just like you would with logEvent by passing in a JSONObject of string key + value pairs. However, these event properties will only appear in the Event Segmentation chart and not in the revenue charts.

Revenue Verification

The logRevenue method also supports revenue validation. See the iOS and Android specific installation documentation for more details. Here is a simple example:

if (Application.platform == RuntimePlatform.IPhonePlayer) {
 Amplitude.Instance.logRevenue("sku", 1, 1.99, "cmVjZWlwdA==", null);
} else if (Application.platform == RuntimePlatform.Android) {
 Amplitude.Instance.logRevenue("sku", 1, 1.99, "receipt", "receiptSignature");
}






The logRevenue method also allows for tracking 'revenueType' and event properties on the revenue event. Here is an example:

Dictionary<string, object> eventProperties = new Dictionary<string, object>() {
 {"Bucket" , "A" },
 {"color" , "blue"}
};

if (Application.platform == RuntimePlatform.IPhonePlayer) {
 Amplitude.Instance.logRevenue("sku", 1, 1.99, "cmVjZWlwdA==", null, "purchase", eventProperties);
} else if (Application.platform == RuntimePlatform.Android) {
 Amplitude.Instance.logRevenue("sku", 1, 1.99, "receipt", "receiptSignature", "purchase", eventProperties);
}











By default, revenue events recorded on the Android SDK will appear in Amplitude as '[Amplitude] Revenue (Unverified)' events. To enable revenue verification, copy your Google Play License Public Key into the Settings section of your project in Amplitude. You must put in a key for every single project in Amplitude where you want revenue to be verified.

By default, revenue events recorded on the iOS SDK will appear in Amplitude as '[Amplitude] Revenue (Unverified)' events. To enable revenue verification, copy your iTunes Connect In-App Purchase Shared Secret into the Settings section of your project in Amplitude. You must put in a key for every single project in Amplitude where you want revenue to be verified.

After a successful purchase transaction, add the purchase data and receipt signature to the Revenue object:

// for a purchase request onActivityResult
String purchaseData = data.getStringExtra("PURCHASE_DATA");
String dataSignature = data.getStringExtra("DATA_SIGNATURE");

Revenue revenue = new Revenue().setProductId("com.company.productId").setQuantity(1);
revenue.setPrice(3.99).setReceipt(purchaseData, dataSignature);

Amplitude.getInstance().logRevenueV2(revenue);
AMPRevenue *revenue = [[[AMPRevenue revenue] setProductIdentifier:@"productIdentifier"] setQuantity:1];
[[revenue setPrice:[NSNumber numberWithDouble:3.99]] setReceipt:receiptData];
[[Amplitude instance] logRevenueV2:revenue];









You can see Google's In-App Billing documentation for details on how to retrieve the purchase data and the receipt signature.

The receipt field should be set to the receipt NSData from the app store. For details on how to obtain the receipt data, see [Apple's guide on receipt validation](Apple's guide on receipt validation).

Amazon Store Revenue Verification

For purchases on the Amazon store, you should copy your Amazon Developer Shared Secret into the Settings section of your project in Amplitude. After a successful purchase transaction, you should send the purchase token as the 'receipt' and the User ID as the 'receiptSignature':

// for a purchase request onActivityResult
String purchaseToken = purchaseResponse.getReceipt();
String userId = getUserIdResponse.getUserId();

Revenue revenue = new Revenue().setProductId("com.company.productId").setQuantity(1);
revenue.setPrice(3.99).setReceipt(purchaseToken, userId);

Amplitude.getInstance().logRevenueV2(revenue);








Backwards Compatibility

The existing logRevenue methods still work but are deprecated. Fields such as revenueType will be missing from events logged with the old methods, so the ability to segment on those revenue events will be limited in the Amplitude platform.

Opting User Out of Logging

You can turn off logging for a given user by calling setOptOut:

amplitude.getInstance().setOptOut(true);
Amplitude.getInstance().setOptOut(true);
Amplitude.Instance.setOptOut(true);
[[Amplitude instance] setOptOut:YES];



No events will be saved or sent to the server while this is enabled. The opt out setting will persist across page loads. You can reenable logging by calling:

amplitude.getInstance().setOptOut(false);
Amplitude.getInstance().setOptOut(false);
Amplitude.Instance.setOptOut(false);
[[Amplitude instance] setOptOut:NO];



SDK Advanced Settings

Platform Specific Settings

This section has information unique to each platform (if nothing shows up, then all information is covered elsewhere).

Getting the Device ID

You can get a user's current Device ID with the following code:

var deviceId = amplitude.getInstance().options.deviceId; // existing device id



Settings Configuration Options

You can configure Amplitude by passing an object as the third argument to the init:

amplitude.getInstance().init("API_KEY", null, {
    // optional configuration options
    saveEvents: true,
    includeUtm: true,
    includeReferrer: true
})







Option Description Default
batchEvents
boolean
If true, then events are batched together and uploaded only when the number of unsent events is greater than or equal to eventUploadThreshold or after eventUploadPeriodMillis milliseconds have passed since the first unsent event was logged. false
cookieExpiration
number
The number of days after which the Amplitude cookie will expire. 365*10
(10 years)
cookieName
string
The custom name for the Amplitude cookie. 'amplitude_id'
deviceId
string
The custom Device ID to set.
Note: This is not recommended unless you know what you are doing (e.g. you have your own system for tracking user devices).
A randomly generated UUID.
deviceIdFromUrlParam
boolean
If true, then the SDK will parse Device ID values from the URL parameter amp_device_id if available. Device IDs defined in the configuration options during init will take priority over Device IDs from URL parameters. null
domain
string
Set a custom domain for the Amplitude cookie.
To include subdomains, add a preceding period, eg:
('.amplitude.com)
The top domain of the current page's URL.
('amplitude.com')
eventUploadPeriodMillis
number
Amount of time in milliseconds that the SDK waits before uploading events if batchEvents is true. 30*1000
(30 sec)
eventUploadThreshold
number
Minimum number of events to batch together per request if batchEvents is true. 30
forceHttps
boolean
If true, the events will always be uploaded to HTTPS endpoint. Otherwise, it will use the embedding site's protocol. true
includeGclid
boolean
If true, captures the gclid URL parameter as well as the user's initial_gclid via a setOnce operation. false
includeReferrer
boolean
If true, captures the referrer and referring_domain for each session, as well as the user's initial_referrer and initial_referring_domain via a setOnce operation. false
includeUtm
boolean
If true, finds UTM parameters in the query string or the _utmz cookie, parses, and includes them as user properties on all events uploaded. This also captures initial UTM parameters for each session via a setOnce operation. false
language
string
Custom language to set. The language determined by the browser.
logLevel
string
Level of logs to be printed in the developer console. Valid values are 'DISABLE', 'ERROR', 'WARN', 'INFO'. To learn more about the different options, see below. 'WARN'
optOut
boolean
Whether or not to disable tracking for the current user. false
platform
string
The custom platform to set. 'Web'
saveEvents
boolean
If true, saves events to localStorage and removes them upon successful upload.
Note: Without saving events, events may be lost if the user navigates to another page before the events are uploaded.
true
savedMaxCount
number
Maximum number of events to save in localStorage. If more events are logged while offline, then old events are removed. 1000
saveParamsReferrerOncePerSession
boolean
If true, then includeGclid, includeReferrer, and includeUtm will only track their respective properties once per session. New values that come in during the middle of the user's session will be ignored. Set to false to always capture new values. true
sessionTimeout
number
The time between logged events before a new session starts in milliseconds. 30*60*1000
(30 min)
uploadBatchSize
number
The maximum number of events to send to the server per request. 100

RequireJS

If you are using RequireJS to load your JavaScript files, then you can also use it to load the Amplitude JavaScript SDK script directly instead of using our loading snippet. On every page that uses analytics, paste the following JavaScript code between the <head> and </head> tags:

<script src='scripts/require.js'></script> <!-- loading RequireJS -->
<script>
 require(['https://cdn.amplitude.com/libs/amplitude-4.1.1-min.gz.js'], function(amplitude) {
 amplitude.getInstance().init('API_KEY'); // replace API_KEY with your Amplitude API key.
 window.amplitude = amplitude; // You can bind the amplitude object to window if you want to use it directly.
 amplitude.getInstance().logEvent('Clicked Link A');
 });
 </script>









You can also define the path in your RequireJS configuration like this:

<script src='scripts/require.js'></script> <!-- loading RequireJS -->
<script>
 requirejs.config({
  paths: {
   'amplitude': 'https://cdn.amplitude.com/libs/amplitude-4.1.1-min.gz.js'
  }
 });

 require(['amplitude'], function(amplitude) {
  amplitude.getInstance().init('API_KEY'); // replace API_KEY with your Amplitude API key.
  window.amplitude = amplitude; // You can bind the amplitude object to window if you want to use it directly.
  amplitude.getInstance().logEvent('Clicked Link A');
 });
</script>
<script>
 require(['amplitude'], function(amplitude) {
  amplitude.getInstance().logEvent('Page loaded');
 });
</script>

















Google Tag Manager

Amplitude's JavaScript SDK supports integration with Google Tag Manager. Take a look at our demo application for instructions on how to set it up.

Cross Domain Tracking

You can track anonymous behavior across two different domains. For example, let's say you have the following two domains:

If you want to track an anonymous user who starts on Site 1 and navigates to Site 2, then you will need to pass the Device ID from Site 1 as a parameter to Site 2. After that, you will need to reinitialize the SDK with the passed Device ID. It would look something like:

Tracking UTM Parameters, Referrer, and gclid

Amplitude supports automatically tracking:

If tracking is enabled, then the SDK will set the values as user properties (e.g. referrer or utm_source) once per session (this is last touch attribution). The SDK will also save the initial values using a setOnce operation (e.g. initial_referrer or initial_utm_source), and once set that value will never change (this is first touch attribution).

Note: By default, the SDK will only save the values at the start of the session. For example, if a user lands on your site with an initial set of UTM parameters and triggers some flow that causes them to land on your site again with a different set of UTM parameters within the same Amplitude session, then that second set will not be saved. You can set the configuration option saveParamsReferrerOncePerSession to false to remove that restriction so that the SDK will always capture any new values from the user.

Setting Version Name

By default, no version name is set. You can specify a version name to distinguish between different versions of your site by calling setVersionName:

amplitude.getInstance().setVersionName('VERSION_NAME');

Callbacks for logEvent, Identify, and Redirect

You can pass a callback function to logEvent and identify, which will get called after receiving a response from the server. This is useful if timing may cause an event to not be captured before the browser navigates away from a webpage. Putting the navigation in a callback to the logEvent method will guarantee the event is captured before the navigation occurs. Here is a logEvent example:

amplitude.getInstance().logEvent("EVENT_TYPE", null, callback_function);

Here is an identify example:

var identify = new amplitude.Identify().set('key', 'value');
amplitude.getInstance().identify(identify, callback_function);




The status and response body from the server are passed to the callback function, which you might find useful. Here is an example of a callback function which redirects the browser to another site after a response:

var callback_function = function(status, response) {
    if (status === 200 && response === 'success') {
        // do something here
    }
    window.location.replace('URL_OF_OTHER_SITE');
};






You can also use this to track outbound links to your website. For example, you would have a link like this:

<a href="javascript:trackClickLinkA();">Link A</a>



Then, you would define a function that is called when the link is clicked like this:

var trackClickLinkA = function() {
    amplitude.getInstance().logEvent('Clicked Link A', null, function() {
        window.location='LINK_A_URL';
    });
};






In the case that optOut is true, then no event will be logged but the callback will be called. In the case that batchEvents is true, if the batch requirements eventUploadThreshold and eventUploadPeriodMillis are not met when logEvent is called, then no request is sent but the callback is still called. In these cases, the callback will be called with an input status of 0 and a response of 'No request sent'.

init Callbacks

You can also pass a callback function to init, which will get called after the SDK finishes its asynchronous loading. Note: The instance is passed as an argument to the callback:

amplitude.getInstance().init('API_KEY', 'USER_ID', null, function(instance) {
  console.log(instance.options.deviceId);  // access Amplitude's deviceId after initialization
});






Fine-Grained Location Tracking

Amplitude can access the Android location service (if possible) to add the specific coordinates (longitude and latitude) where an event is logged. This behavior is enabled by default but can be adjusted by calling the following methods after initializing:

Amplitude.getInstance().enableLocationListening();
Amplitude.getInstance().disableLocationListening();



Even if location listening is disabled, the events will still have the '[Amplitude] Country' property filled. This is because that property is retrieved from other sources (e.g. network or device locale).

Location Tracking

If the user granted your app location permissions, then the SDK will also grab the location of the user. Amplitude will never prompt the user for location permissions and this will have to be done by your app.

Amplitude only polls for a location once on launch of the app, once on each app open, and once when the permission is first granted. There is no continuous tracking of location, although you can force Amplitude to grab the latest location by calling [[Amplitude instance] updateLocation]. Note: This does consume more resources on the user's device, so use this wisely.

If you wish to disable location tracking done by the app, you can call [[Amplitude instance] disableLocationListening] at any point. If you want location tracking disabled on startup of the app, call disableLocationListening before you call initializeApiKey:. You can always re-enable location tracking through Amplitude with [[Amplitude instance] enableLocationListening].

SSL Pinning

The SDK includes support for SSL pinning, but it is undocumented and recommended against unless you have a specific need. Please contact Amplitude support before you ship any products with SSL pinning enabled so that we are aware and can provide documentation and implementation help.

tvOS

This SDK will work with tvOS apps. To begin, follow the same setup instructions for iOS apps.

Note: tvOS apps do not have persistent storage (they only have temporary storage), so for tvOS the SDK is configured to upload events immediately as they are logged. This means eventUploadThreshold is set to 1 by default for tvOS. It is assumed that Apple TV devices have a stable internet connection and as a result, uploading events immediately is reasonable. If you wish to revert back to the iOS batching behavior, you can do so by changing eventUploadThreshold (this is set by default to 30 for iOS):

[[Amplitude instance] setEventUploadThreshold:30];

Swift

This SDK will work with Swift. If you are copying the source files or using CocoaPods without the use_frameworks! directive, you should create a bridging header as documented here and add the following line to your bridging header:

#import 'Amplitude.h'

If you have use_frameworks! set, you should not use a bridging header and instead use the following line in your Swift files:

import Amplitude_iOS

In either case, you can call Amplitude methods with:

Amplitude.instance().method(...)

Setting User Groups

Note: This feature is only available for Growth customers who have purchased the Accounts add-on.

Amplitude supports assigning users to groups and performing queries such as Count by Distinct on those groups. An example would be if you want to group your users based on what organization they are in by using an 'orgId'. You can designate Joe to be in 'orgId' '10' while Sue is in 'orgId' '15'. When performing a query in our Event Segmentation chart, you can then select "..performed by" 'orgId' to query the number of different organizations that have performed a specific event. As long as at least one member of that group has performed the specific event, that group will be included in the count.

When setting groups, you will need to define a groupType and groupName(s). In the above example, 'orgId' is the groupType and the values '10' and '15' are groupName(s). Another example of a groupType could be 'sport' with groupName(s) like 'tennis' and 'baseball'. You can use setGroup(groupType, groupName) to designate which groups a user belongs to. Note: This will also set the 'groupType:groupName' as a user property. This will overwrite any existing groupName value set for that user's groupType, as well as the corresponding user property value. groupType is a string and groupName can be either a string or an array of strings to indicate a user being in multiple groups (for example, if Joe is in 'orgId' '10' and '16', then the groupName would be '[10, 16]'). Here is what your code might look like:

amplitude.getInstance().setGroup('orgId', '15');
amplitude.getInstance().setGroup('sport', ['soccer', 'tennis']);
Amplitude.getInstance().setGroup("orgId", "15");
Amplitude.getInstance().setGroup("sport", new JSONArray().put("tennis").put("soccer"));  // list values
[[Amplitude instance] setGroup:@"orgId" groupName:[NSNumber numberWithInt:15]];
[[Amplitude instance] setGroup:@"sport" groupName:[NSArray arrayWithObjects: @"tennis", @"soccer", nil];




You can also use logEventWithGroups to set event-level groups, meaning the group designation only applies for the specific event being logged and does not persist on the user unless you explicitly set it with setGroup:

var eventProperties = {
  'key': 'value'
}

amplitude.getInstance().logEventWithGroups('initialize_game', eventProperties, {'sport': 'soccer'});
JSONObjecteventProperties=newJSONObject().put("key", "value");
JSONObjectgroups=newJSONObject().put("orgId", 10);

Amplitude.getInstance().logEvent("initialize_game", eventProperties, groups);
NSDictionary *eventProperties = [NSDictionary dictionaryWithObjectsAndKeys: @"value", @"key", nil];
NSDictionary *groups = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:10],
    @"orgId", @"soccer", @"sport", nil];
[[Amplitude instance] logEvent:@"initialize_game" withEventProperties:eventProperties withGroups:groups];






Setting Date Values

Amplitude compares dates as strings, so it is recommended to use the ISO 8601 format (YYYY-MM-DDTHH:mm:ss), which will allow you to perform date comparisons in the platform (e.g. '2016-01-31' > '2016-01-01'). This will also work for datetime values (e.g. '2017-08-07T10:09:08' > '2017-08-07T01:07:00').

Custom Device IDs

By default, device IDs are randomly generated UUIDs, although you can define a custom Device ID by setting it as a configuration option or by calling:

amplitude.getInstance().setDeviceId('DEVICE_ID');
Amplitude.getInstance().setDeviceId("DEVICE_ID")
[[Amplitude instance] setDeviceId:@"DEVICE_ID"]



If you would like to use Google's Advertising ID as the Device ID, you can specify this by calling Amplitude.getInstance().useAdvertisingIdForDeviceId() prior to initializing. You can retrieve the Device ID that Amplitude uses with Amplitude.getInstance().getDeviceId(). This method can return null if a Device ID has not been generated yet.

Note: This is not recommended unless you know what you are doing (like if you have your own system for tracking user devices). Make sure the deviceId you set is sufficiently unique in order to prevent conflicts with other devices in our system. We recommend something like a UUID.

See here for an example of how to generate.

We use UUID.randomUUID().toString()

Log Level

The log level allows you to set the level of logs printed to be printed in the developer console. The different levels are as follows:

You can set the log level by calling:

Amplitude.getInstance().setLogLevel(log.DEBUG)

You can set the logLevel configuration option

HTTP API

Use the HTTP API to send data directly from your server to our endpoint.

Important Notes

Upload Limit

Limit your upload to 100 batches/sec and 1000 events/sec. You can batch events into an upload but we recommend not sending more than 10 events per batch. Thus, we expect at most 100 batches to be sent per second, and so the 1000 events/sec limit still applies as we do not recommend sending more than 10 events per batch. Note: This applies to customers on our Starter Plan only.

For paying customers, please reach out to us if you need to send more than 1000 events/sec. There is no hard limit on the Amplitude Enterprise plan. However, please note that we will throttle requests for individual devices that exceed 10 events/second as stated in the below HTTP status codes section.

For request size, please limit your requests to no more than 2000 events per request and under 1 MB. If you exceed these size limits, you will receive a 413 error.

Recommendation: For high volume customers concerned with scale, please partition your work based on device_id (or user_id if you don't have a device_id). This ensures that throttling on a particular device_id (or user_id) doesn't impact all senders in your system. If you are proxying events to Amplitude, please ensure that throttling is forwarded to your clients to create backpressure instead of letting spammy clients slow down a partition of work in your system.

All Zero Device IDs: Limited Ad Tracking Enabled

As of iOS 10, if the user enables Limit Ad Tracking, Apple will replace the Identifier for Advertiser (IDFA) with all zeros. Amplitude will drop a Device ID of all zeros from the event and return an error on the request (since Device IDs are required for all events). Thus, if you are passing the IDFA as the Device ID, then we recommend running a check on the IDFA value and passing a different Device ID value like the Identifier for Vendor (IDFV) instead.

Windows Operating System

If you are using a Windows operating system, then you may have to replace all single quotes with double quotes and escape all double quotes as well.

String Character Limit

There is a character limit of 1024 characters for all string values (user_id, event or user property values, etc.).

Setting Date Values

Amplitude compares dates as strings, so it is recommended to use the ISO 8601 format (YYYY-MM-DDTHH:mm:ss), which will allow you to perform date comparisons in the platform, (e.g. '2016-01-31' > '2016-01-01'). This will also work for datetime values (e.g. '2017-08-07T10:09:08' > '2017-08-07T01:07:00').

Event Deduplication

It is highly recommended that you send an insert_id for each event to prevent duplicate events from being received by Amplitude. We will ignore subsequent events sent with the same insert_id within the past 7 days. You can read more about this field below.

Request Format

Send a POST or GET request to https://api.amplitude.com/httpapi with two request parameters:

Required Argument Description
api_key API key which can be found in your project's Settings page.

"040062a5d38552315b98302ba4f2f"
event Either a single JSON event object (see below for fields) or an array of JSON objects, each of which represents one event.

See below for examples.

IMPORTANT NOTE: Special characters need to be URL encoded. For example, if your event is named "event name", it needs to be formatted as "event20%name" in your request.

HTTP Status Codes & Retrying Failed Requests

It's important that you implement retry logic and send an insert_id, in the unlikely event that our API endpoint becomes unavailable and we are unable to ingest events. If you do not receive a 200 status code (which means your event was successfully received by Amplitude), then you should retry your request. Here are the other HTTP status codes you may receive:

Example Requests

Sending a POST event call request:

curl --data 'api_key={API_KEY}' --data-urlencode 'event=[{"user_id":"datamonster@gmail.com",
    "event_type":"watch_tutorial", "user_properties":{"Cohort":"Test A"}, "country":"United States",
    "ip":"127.0.0.1", "time":1396381378123}]' https://api.amplitude.com/httpapi







Sending a POST Identify call request:

curl --data 'api_key={API_KEY}' --data-urlencode 'event=[{"user_id":"datamonster@gmail.com",
    "event_type":"$identify", "user_properties":{"$set": {"Cohort":"Test B"},
    "$add": {"friendCount":3}}, "country":"United States", "ip":"127.0.0.1",
    "time":1396381378123}]' https://api.amplitude.com/httpapi







Sending a GET event call request:

curl -v 'https://api.amplitude.com/httpapi?api_key={API_KEY}&event=%5B%7B%22 user_id%22%3A%22datamonster%40gmail.com%22%2C%20%22event_type%22%3A%22 watch_tutorial%22%2C%20%22user_properties%22%3A%7B%22Cohort%22%3A%22 Test%20A%22%7D%2C%20%22country%22%3A%22United%20States%22%2C%20%22 ip%22%3A%22127.0.0.1%22%2C%20%22time%22%3A1396381378123%7D%5D'





Note that in this GET request, the body of the event (same as the one from the POST request) is URL encoded.

Keys for the Event Argument

The following keys can be sent within the JSON event object. Note that one of user_id or device_id is required, as well as the event_type.

Note: '[Amplitude] Country', '[Amplitude] City', '[Amplitude] Region', and '[Amplitude] DMA' are user properties pulled using GeoIP. For any HTTP API events, if GeoIP information is unavailable, then we pull the information from the 'location_lat' and 'location_lng' keys if those keys are populated. If these location properties are manually set, then Amplitude will not modify that property.

IMPORTANT NOTE: This should not be used if device_brand, device_manufacturer, and device_model are used.

Key Description
user_id
string
(required unless device_id is present) A readable ID specified by you.

"datamonster@gmail.com"
device_id
string
(required unless user_id is present) A device specific identifier, such as the Identifier for Vendor on iOS.

"C8F9E604-F01A-4BD9-95C6-8E5357DF265D"

Note: If a Device ID is not sent with the event, Device ID will be set to a hashed version of that user's User ID.
event_type
string
(required) A unique identifier for your event.

IMPORTANT NOTE: The following event names are reserved for Amplitude use: "[Amplitude] Start Session", "[Amplitude] End Session", "[Amplitude] Revenue", "[Amplitude] Revenue (Verified)", "[Amplitude] Revenue (Unverified)", and "[Amplitude] Merged User". You should not send server-side events with these same names.

"watch_tutorial"
time
long
The timestamp of the event in milliseconds since epoch. It will be set to the upload time by default.

1396381378123
event_properties4
dictionary
A dictionary of key-value pairs that represent additional data to be sent along with the event.

Note: You can store property values in an array, and date values are transformed into string values.

user_properties4
dictionary
A dictionary of key-value pairs that represent additional data tied to the user. Each distinct value will show up as a user segment on the Amplitude dashboard.
</br/>Note: You can store property values in an array, and date values are transformed into string values.

{"age": 25, "gender": "female", "interests": ["chess", "football", "music"]}

In addition, user property operations ($set, $setOnce, $add, $append, $unset) are only supported with an Identify call within the HTTP API; please set:

"event_type":"$identify"

Similar to calls via Identify API, user property values updated by an Identified call will not reflect on any Amplitude charts until the user's following event. And you cannot mix user property operations with actual top-level user properties; instead, include them inside the "$set" operation. If you are using one of these operators then this dictionary can only contain user property operations and cannot be combined with the above format e.g. you cannot do {"$append":{"interests":"Music"}, "subscription type":"paid"} in the same request.

{"$set": {"cohort": "Test A"}, "$setOnce": {"startDate": "2015-10-01"}, "$add": {"friendCount": 3}, "$append": {"interests": "Music"}, "$prepend":{"sports": "Tennis"}, "$unset":
groups4
dictionary
(Enterprise only) This feature is only available to Enterprise customers who have purchased the Accounts add-on. This field adds a dictionary of key-value pairs that represent groups of users to the event as an event-level group. See this excerpt in our Javascript SDK for more information on groups. Instrumenting groups will allow you to utilize our account-level reporting.

In the example below, "company_id" and "company_name" are groupType(s), while "1" and ["Amplitude", "DataMonster"] are groupName(s).

Note: You can only track up to 5 groups. Any groups pass that threshold will not be tracked. This field also sets an event-level group, meaning the group designation only applies for the specific event being logged and does not persist on the user unless you explicitly set it through Amplitude's SDKs or through the Identify API.

app_version
string
The version of your application the user is on.

"2.1.3"
platform1, 2
string
Platform of the device.

"iOS", "Android", or "Web"
os_name1, 2
string
The mobile operating system or browser the user is on.

"iOS", "Android", "Chrome"
os_version1, 2
string
The version of the mobile operating system or browser the user is on.

"8.1", "4.2.2", "37"
device_brand1, 2
string
The device brand the user is on.

"Verizon"
device_manufacturer1, 2
string
The device manufacturer the user is on.

"Samsung", "Asus", "Apple"
device_model1, 2
string
The device model the user is on.

"Mac", "iphone 9,1", "sm-g30f"
carrier1, 2
string
Carrier of the device.

"Verizon"
country1, 3
string
The country the user is in.

"United States"
region1, 3
string
The geographical region the user is in.

"California"
city1, 3
string
What city the user is in.
"San Francisco"
dma1, 3
string
The Designated Market Area of the user.

"San Francisco-Oakland-San Jose, CA"
language1
string
What language the user has set.

"English"
price5
float
(required for revenue data if revenue is not sent) The price of the item purchased. You can use negative values to indicate refunds.

4.99, -1.99
quantity5
integer
(required for revenue data, defaults to 1 if not specified) The quantity of the item purchased.

1, 2
revenue5
float
revenue = price * quantity

If you send all three fields of price, quantity, and revenue, then (price * quantity) will take precedence and be the revenue value. You can use negative values to indicate refunds.

4.99, -1.99
productId5
string
An identifier for the product.

Note: You must send a price and quantity with this field.

"Google Play Store Product Id", "Medium Bundle"
revenueType5
string
Type of revenue.

Note: You must send a price and quantity with this field.

"tax", "refund"
location_lat
float
Latitude of the user.

37.77
location_lng
float
Longitude of the user.

-122.39
ip1
string
IP address of the user. Use "$remote" to use your server's IP address. We will then use the collected IP address to reverse lookup a user's location user properties (City, Country, Region, and DMA). However, Amplitude has the ability to drop this data once it reaches our servers. If you'd like to drop IP address, Latitude and Longitude, or City and DMA information from your data, please submit a request to our team of Platform Specialists here and they can configure this for you.

"127.0.0.1"
idfa
string
(iOS) Identifier for Advertiser.

"AEBE52E7-03EE-455A-B3C4-E57283966239"
idfv
string
(iOS) Identifier for Vendor.

"BCCE52E7-03EE-321A-B3D4-E57123966239"
adid
string
(Android) Google Play Services advertising ID (AdID).

"AEBE52E7-03EE-455A-B3C4-E57283966239"
android_id
string
(Android) Android ID (not the advertising ID).

"BCCE52E7-03EE-321A-B3D4-E57123966239"

Footnotes

  1. These user properties and all other user properties persist in following events if not explicitly changed at the time of subsequent events (as of 06/24/2016). Please refer to footnotes 2 and 3 to assure that you update these properties appropriately.

  2. These fields (platform, os_name, os_version, device_brand, device_manufacturer, device_model, and carrier) must all be updated together. Setting any of these fields will automatically reset all of the other property values to null if they are not also explicitly set for the same event. All property values will otherwise persist to a subsequent event if the values are not changed to a different string or if all values are passed as null. Amplitude will attempt to use device_brand, device_manufacturer, and device_model to map the corresponding device type.

  3. These fields (country, region, city, DMA) must all be updated together. Setting any of these fields will automatically reset all of the other property values to null if they are not also explicitly set for the same event. All property values will otherwise persist to a subsequent event if the values are not changed to a different string or if all values are passed as null.

  4. To implement property values as arrays, restructure the key-value pairs as follows: "property_name": [value1, value2, value3]. Note: For all event/user properties that Amplitude automatically tracks, you cannot store their values as an array. For example, you cannot store the values of '[Amplitude] Country' as an array.

  5. If this field is populated with a non-zero value, then the event is assumed to be a revenue event.

Optional Keys

The following optional keys are interpreted in a special way on our backend.

Optional Amplitude Specific Key Description
event_id
int
An incrementing counter to distinguish events with the same user_id and timestamp from each other.

Note: We recommend you send an event_id, increasing over time, especially if you suspect any events to occur simultaneously. An event_id is not required to send a session_id though.

1
session_id
long
The start time of the session in milliseconds since epoch (Unix Timestamp), necessary if you want to associate events with a particular session (a session_id of -1 implies that you not sending a session_id, and so no session metrics will be tracked). Here is more information.

1396381378123
insert_id
string
A unique identifier for the event being inserted; we will deduplicate subsequent events sent with an insert_id we have already seen before within the past 7 days.

Some combination of device_id, user_id, session_id, event_type, and event_id or time, would likely serve as a sufficient insert_id value.

"f47ac10b-58cc-4372-a567-0e02b2c3d479"

Common Issues with HTTP API Implementations

There are some considerations related to using the HTTP API rather than using our client libraries. Some of these relate to product analytics, and some are primarily technical.

Product Analytics Considerations

It is important to make sure that everything you want to log is represented in your server API. For example, in a funnel, you may only send a single call to the server at the end, but you might want to track the user as they progress through the steps.

Also, there is context that might not be tracked on the server. An example is the location where an action was performed (if there is more than one way to perform an action), which might not be passed to the server.

To make sure that everything required is available server-side, you can start by writing out the flows you want to track, and making sure that all of the events and event properties are represented by API calls.

Technical Considerations

There are some things that the client SDKs take care of that you have to handle by yourself if you do the tracking server-side. The main things are session ids, insert ids and retry/connection logic.

Amplitude's data collection endpoints have extremely high uptime, but there are very occasionally small outages, or you could hit the rate limits if you're sending a lot of data from your server. As a result, it's important that your retry logic is correct if you want to make sure that everything is logged correctly.

Our client libraries store up to 1000 events and will retry if the events aren't sent successfully

Make sure to familiarize yourself with our HTTP response codes, and that your server handles them correctly.

Also make sure you are familiar with our insert_id, which allow us to deduplicate events if you happen to send duplicate events.

Finally, the session_id has to be in a specific format (ms since the epoch) for us to track them properly. Both session_id and insert_id are covered in the above section.

Batch Event Upload API (BETA)

The Batch Event Upload endpoint accepts JSON requests that contain an API key and a list of events.

The JSON serialized payload must not exceed 20MB in size.

The event JSON format follows our HTTP API format, and has the same requirements (such as each event must have an event type, etc).

NOTE: In addition, device IDs and user IDs must be strings with a length of 5 characters or more. This is to prevent potential instrumentation issues. If an event contains a device or user ID that is too short, the ID value will be removed from the event. This may cause the upload to be rejected with a 400 error if that event does not have a user ID or device ID value.

Each API key is allowed to send up to 1000 events per second for any individual device / user Id. If you exceed that rate your upload will be rejected with a response code of 429. The response summary will indicate which device / user Ids have exceeded the limit, what their current events per second rate is, along with some other useful information. See below for more details.

See Amplitude Help Center for more support articles and documentation.

Base URLs:

Terms of service
Email: Support
License: MIT License

Post Batch

Code samples

# You can also use wget
curl -X POST http://api.amplitude.com//batch \
  -H 'Content-Type: application/json' \
  -H 'Accept: */*'

POST http://api.amplitude.com//batch HTTP/1.1
Host: api.amplitude.com
Content-Type: application/json
Accept: */*

var headers = {
  'Content-Type':'application/json',
  'Accept':'*/*'

};

$.ajax({
  url: 'http://api.amplitude.com//batch',
  method: 'post',

  headers: headers,
  success: function(data) {
    console.log(JSON.stringify(data));
  }
})

const request = require('node-fetch');
const inputBody = '{
  "api_key": "my_amplitude_api_key",
  "events": [
    {
      "user_id": "datamonster@gmail.com",
      "device_id": "C8F9E604-F01A-4BD9-95C6-8E5357DF265D",
      "event_type": "watch_tutorial",
      "time": 1396381378123,
      "event_properties": {
        "load_time": 0.8371,
        "source": "notification",
        "dates": [
          "monday",
          "tuesday"
        ]
      },
      "user_properties": {
        "age": 25,
        "gender": "female",
        "interests": [
          "chess",
          "football",
          "music"
        ]
      },
      "groups": {
        "company_id": "1",
        "company_name": [
          "Amplitude",
          "DataMonster"
        ]
      },
      "app_version": "2.1.3",
      "platform": "iOS",
      "os_name": "Android",
      "os_version": "4.2.2",
      "device_brand": "Verizon",
      "device_manufacturer": "Apple",
      "device_model": "iPhone 9,1",
      "carrier": "Verizon",
      "country": "United States",
      "region": "California",
      "city": "San Francisco",
      "dma": "San Francisco-Oakland-San Jose, CA",
      "language": "English",
      "price": 4.99,
      "quantity": 3,
      "revenue": -1.99,
      "productId": "Google Pay Store Product Id",
      "revenueType": "Refund",
      "location_lat": 37.77,
      "location_lng": -122.39,
      "ip": "127.0.0.1",
      "idfa": "AEBE52E7-03EE-455A-B3C4-E57283966239",
      "idfv": "BCCE52E7-03EE-321A-B3D4-E57123966239",
      "adid": "AEBE52E7-03EE-455A-B3C4-E57283966239",
      "android_id": "BCCE52E7-03EE-321A-B3D4-E57123966239",
      "event_id": 23,
      "session_id": 1396381378123,
      "insert_id": "5f0adeff-6668-4427-8d02-57d803a2b841"
    }
  ]
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'*/*'

};

fetch('http://api.amplitude.com//batch',
{
  method: 'POST',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'application/json',
  'Accept' => '*/*'
}

result = RestClient.post 'http://api.amplitude.com//batch',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': '*/*'
}

r = requests.post('http://api.amplitude.com//batch', params={

}, headers = headers)

print r.json()

URL obj = new URL("http://api.amplitude.com//batch");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("POST");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Content-Type": []string{"application/json"},
        "Accept": []string{"*/*"},

    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("POST", "http://api.amplitude.com//batch", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

POST /batch

Bulk upload events

Bulk upload events to Amplitude via the batch event upload endpoint.

Body parameter

{
  "api_key": "my_amplitude_api_key",
  "events": [
    {
      "user_id": "datamonster@gmail.com",
      "device_id": "C8F9E604-F01A-4BD9-95C6-8E5357DF265D",
      "event_type": "watch_tutorial",
      "time": 1396381378123,
      "event_properties": {
        "load_time": 0.8371,
        "source": "notification",
        "dates": [
          "monday",
          "tuesday"
        ]
      },
      "user_properties": {
        "age": 25,
        "gender": "female",
        "interests": [
          "chess",
          "football",
          "music"
        ]
      },
      "groups": {
        "company_id": "1",
        "company_name": [
          "Amplitude",
          "DataMonster"
        ]
      },
      "app_version": "2.1.3",
      "platform": "iOS",
      "os_name": "Android",
      "os_version": "4.2.2",
      "device_brand": "Verizon",
      "device_manufacturer": "Apple",
      "device_model": "iPhone 9,1",
      "carrier": "Verizon",
      "country": "United States",
      "region": "California",
      "city": "San Francisco",
      "dma": "San Francisco-Oakland-San Jose, CA",
      "language": "English",
      "price": 4.99,
      "quantity": 3,
      "revenue": -1.99,
      "productId": "Google Pay Store Product Id",
      "revenueType": "Refund",
      "location_lat": 37.77,
      "location_lng": -122.39,
      "ip": "127.0.0.1",
      "idfa": "AEBE52E7-03EE-455A-B3C4-E57283966239",
      "idfv": "BCCE52E7-03EE-321A-B3D4-E57123966239",
      "adid": "AEBE52E7-03EE-455A-B3C4-E57283966239",
      "android_id": "BCCE52E7-03EE-321A-B3D4-E57123966239",
      "event_id": 23,
      "session_id": 1396381378123,
      "insert_id": "5f0adeff-6668-4427-8d02-57d803a2b841"
    }
  ]
}

Parameters

Parameter In Type Required Description
body body UploadRequestBody true A JSON object containing your api_key and an array of events

Example responses

200 Response

400 Response

413 Response

429 Response

Responses

Status Meaning Description Schema
200 OK Successful batch event upload SuccessSummary
400 Bad Request A 400 indicates invalid upload request. Possible reasons for invalid request:

The request body is not valid JSON. The error will say "Invalid JSON request body".

The request body is missing at least one of: required api_key and events array of at least one event. The error will say "Request missing required field". The missing_field will indicate which is missing.

At least one of the events in the request is missing a required field. The error will say "Request missing required field". The events_missing_required_fields will be a map from field names to an array of indexes indicating the events missing those required fields.

At least one of the events in the request has an invalid value for one of the fields (for example setting a string for the time field). The error will say "Invalid field values on some events". The events_with_invalid_fields will be a map from field names to an array of indexes indicating the events with invalid values for those fields.|InvalidRequestError|
|413|Payload Too Large|Payload size is too big (request size exceeds 20MB). You should split your events array payload in half and try again.|PayloadTooLargeError|
|429|Too Many Requests|Too many requests for a user / device. Amplitude will throttle requests for users and devices that exceed 1000 events per second (measured as an average over a recent time window). You should pause sending events for that user / device for a period of 30 seconds before retrying and continue retrying until you no longer receive a 429 response.|TooManyRequestsForDeviceError|

UploadRequestBody

{
  "api_key": "my_amplitude_api_key",
  "events": [
    {
      "user_id": "datamonster@gmail.com",
      "device_id": "C8F9E604-F01A-4BD9-95C6-8E5357DF265D",
      "event_type": "watch_tutorial",
      "time": 1396381378123,
      "event_properties": {
        "load_time": 0.8371,
        "source": "notification",
        "dates": [
          "monday",
          "tuesday"
        ]
      },
      "user_properties": {
        "age": 25,
        "gender": "female",
        "interests": [
          "chess",
          "football",
          "music"
        ]
      },
      "groups": {
        "company_id": "1",
        "company_name": [
          "Amplitude",
          "DataMonster"
        ]
      },
      "app_version": "2.1.3",
      "platform": "iOS",
      "os_name": "Android",
      "os_version": "4.2.2",
      "device_brand": "Verizon",
      "device_manufacturer": "Apple",
      "device_model": "iPhone 9,1",
      "carrier": "Verizon",
      "country": "United States",
      "region": "California",
      "city": "San Francisco",
      "dma": "San Francisco-Oakland-San Jose, CA",
      "language": "English",
      "price": 4.99,
      "quantity": 3,
      "revenue": -1.99,
      "productId": "Google Pay Store Product Id",
      "revenueType": "Refund",
      "location_lat": 37.77,
      "location_lng": -122.39,
      "ip": "127.0.0.1",
      "idfa": "AEBE52E7-03EE-455A-B3C4-E57283966239",
      "idfv": "BCCE52E7-03EE-321A-B3D4-E57123966239",
      "adid": "AEBE52E7-03EE-455A-B3C4-E57283966239",
      "android_id": "BCCE52E7-03EE-321A-B3D4-E57123966239",
      "event_id": 23,
      "session_id": 1396381378123,
      "insert_id": "5f0adeff-6668-4427-8d02-57d803a2b841"
    }
  ]
}

Properties

Name Type Required Restrictions Description
api_key string true none Amplitude project API key
events [Event] true none Array of Events to upload

Event

{
  "user_id": "datamonster@gmail.com",
  "device_id": "C8F9E604-F01A-4BD9-95C6-8E5357DF265D",
  "event_type": "watch_tutorial",
  "time": 1396381378123,
  "event_properties": {
    "load_time": 0.8371,
    "source": "notification",
    "dates": [
      "monday",
      "tuesday"
    ]
  },
  "user_properties": {
    "age": 25,
    "gender": "female",
    "interests": [
      "chess",
      "football",
      "music"
    ]
  },
  "groups": {
    "company_id": "1",
    "company_name": [
      "Amplitude",
      "DataMonster"
    ]
  },
  "app_version": "2.1.3",
  "platform": "iOS",
  "os_name": "Android",
  "os_version": "4.2.2",
  "device_brand": "Verizon",
  "device_manufacturer": "Apple",
  "device_model": "iPhone 9,1",
  "carrier": "Verizon",
  "country": "United States",
  "region": "California",
  "city": "San Francisco",
  "dma": "San Francisco-Oakland-San Jose, CA",
  "language": "English",
  "price": 4.99,
  "quantity": 3,
  "revenue": -1.99,
  "productId": "Google Pay Store Product Id",
  "revenueType": "Refund",
  "location_lat": 37.77,
  "location_lng": -122.39,
  "ip": "127.0.0.1",
  "idfa": "AEBE52E7-03EE-455A-B3C4-E57283966239",
  "idfv": "BCCE52E7-03EE-321A-B3D4-E57123966239",
  "adid": "AEBE52E7-03EE-455A-B3C4-E57283966239",
  "android_id": "BCCE52E7-03EE-321A-B3D4-E57123966239",
  "event_id": 23,
  "session_id": 1396381378123,
  "insert_id": "5f0adeff-6668-4427-8d02-57d803a2b841"
}

Properties

Name Type Required Restrictions Description
user_id string true none A readable ID specified by you. Must have a minimum length of 5 characters. Required unless device_id is present.
device_id string true none A device-specific identifier, such as the Identifier for Vendor on iOS. Required unless user_id is present. If a device_id is not sent with the event, it will be set to a hashed version of the user_id.
event_type string true none A unique identifier for your event.
time long false none The timestamp of the event in milliseconds since epoch. If time is not sent with the event, it will be set to the request upload time.
event_properties object false none A dictionary of key-value pairs that represent additional data to be sent along with the event. You can store property values in an array. Date values are transformed into string values.
user_properties object false none A dictionary of key-value pairs that represent additional data tied to the user. You can store property values in an array. Date values are transformed into string values.
groups object false none This feature is only available to Enterprise customers who have purchased the Accounts add-on. This field adds a dictionary of key-value pairs that represent groups of users to the event as an event-level group. You can only track up to 5 groups.
app_version string false none The current version of your application.
platform string false none Platform of the device.
os_name string false none The version of the mobile operating system or browser that the user is using.
os_version string false none The version of the mobile operating system or browser the user is using.
device_brand string false none The device brand that the user is using.
device_manufacturer string false none The device manufacturer that the user is using.
device_model string false none The device model that the user is using.
carrier string false none The carrier that the user is using.
country string false none The current country of the user.
region string false none The current region of the user.
city string false none The current city of the user.
dma string false none The current Designated Market Area of the user.
language string false none The language set by the user.
price float false none The price of the item purchased. Required for revenue data if the revenue field is not sent. You can use negative values to indicate refunds.
quantity integer false none The quantity of the item purchased. Defaults to 1 if not specified.
revenue float false none revneue = price * quantity. If you send all 3 fields of price, quantity, and revenue, then (price * quantity) will be used as the revenue value. You can use negative values to indicate refunds.
productId string false none An identifier for the item purchased. You must send a price and quantity or revenue with this field.
revenueType string false none The type of revenue for the item purchased. You must send a price and quantity or revenue with this field.
location_lat float false none The current Latitude of the user.
location_lng float false none The current Longitude of the user.
ip string false none The IP address of the user. Use "$remote" to use the IP address on the upload request. We will use the IP address to reverse lookup a user's location (city, country, region, and DMA). Amplitude has the ability to drop the location and IP address from events once it reaches our servers. You can submit a request to our platform specialist team here to configure this for you.
idfa string false none (iOS) Identifier for Advertiser.
idfv string false none (iOS) Identifier for Vendor.
adid string false none (Android) Google Play Services advertising ID
android_id string false none (Android) Android ID (not the advertising ID)
event_id int false none (Optional) An incrementing counter to distinguish events with the same user_id and timestamp from each other. We recommend you send an event_id, increasing over time, especially if you expect events to occur simultanenously.
session_id long false none (Optional) The start time of the session in milliseconds since epoch (Unix Timestamp), necessary if you want to associate events with a particular system. A session_id of -1 is the same as no session_id specified.
insert_id string false none (Optional) A unique identifier for the event. We will deduplicate subsequent events sent with an insert_id we have already seen before within the past 7 days. We recommend generation a UUID or using some combination of device_id, user_id, event_type, event_id, and time.

SuccessSummary

{
  "code": 200,
  "events_ingested": 50,
  "payload_size_bytes": 50,
  "server_upload_time": 1396381378123
}

Properties

Name Type Required Restrictions Description
code integer false none 200 success code
events_ingested integer false none The number of events ingested from the upload request.
payload_size_bytes integer false none The size of the upload request payload in bytes.
server_upload_time long false none The time in milliseconds since epoch (Unix Timestamp) that our event servers accepted the upload request.

InvalidRequestError

{
  "code": 400,
  "error": "Request missing required field",
  "missing_field": "api_key",
  "events_with_invalid_fields": {
    "time": [
      3,
      4,
      7
    ]
  },
  "events_with_missing_fields": {
    "event_type": [
      3,
      4,
      7
    ]
  }
}

Properties

Name Type Required Restrictions Description
code integer false none 400 error code
error string false none Error description. Possible values are Invalid request path, Missing request body, Invalid JSON request body, Request missing required field, Invalid event JSON, Invalid API key, Invalid field values on some events
missing_field string false none Indicates which request-level required field is missing.
events_with_invalid_fields object false none A map from field names to an array of indexes into the events array indicating which events have invalid valids for those fields
events_with_missing_fields object false none A map from field names to an array of indexes into the events array indicating which events are missing those required fields

PayloadTooLargeError

{
  "code": 413,
  "error": "Payload too large"
}

Properties

Name Type Required Restrictions Description
code integer false none 413 error code
error string false none Error description.

TooManyRequestsForDeviceError

{
  "code": 429,
  "error": "Too many requests for some devices and users",
  "eps_threshold": 1000,
  "throttled_devices": {
    "C8F9E604-F01A-4BD9-95C6-8E5357DF265D": 4000
  },
  "throttled_users": {
    "datamonster@amplitude.com": 4000
  },
  "throttled_events": [
    3,
    4,
    7
  ]
}

Properties

Name Type Required Restrictions Description
code integer false none 429 error code
error string false none Error description.
eps_threshold integer false none Your app's current events per second threshold. If you exceed this rate your requests will be throttled.
throttled_devices object false none A map from device_id to its current events per second rate, for all devices that exceed the app's current threshold.
throttled_users object false none A map from user_id to their current events per second rate, for all users that exceed the app's current threshold
throttled_events [integer] false none Array of indexes in the oevents array indicating events whose user_id and/or device_id got throttled

User Privacy API

Scroll down for code samples, example requests and responses. Select a language for code samples from the tabs above or the mobile navigation menu.

Please note that this API is currently available by request only. Contact Amplitude or your Success Manager to get access and receive more information. This API will be publicly available on May 25.
In order to ensure that our Customers can appropriately respond to and comply with GDPR User data deletion requests, we've built a simple an easy-to-use API endpoint that allows you to programmatically submit requests to delete all data for set of known Amplitude IDs and/or User IDs.
This system also communicates status updates to the administrators of your Organization so you can be confident you have fully complied with your Customers privacy requests.

Base URLs:

Terms of service
Email: Support

Authentication

Delete a user

Code samples

# You can also use wget
curl -X POST https://amplitude.com/api/2/deletions/users \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json'

POST https://amplitude.com/api/2/deletions/users HTTP/1.1
Host: amplitude.com
Content-Type: application/json
Accept: application/json

var headers = {
  'Content-Type':'application/json',
  'Accept':'application/json'

};

$.ajax({
  url: 'https://amplitude.com/api/2/deletions/users',
  method: 'post',

  headers: headers,
  success: function(data) {
    console.log(JSON.stringify(data));
  }
})

const request = require('node-fetch');
const inputBody = '{
  "amplitude_ids": [
    "amp_id_1",
    "amp_id_2",
    "..."
  ],
  "user_ids": [
    "user_id_1",
    "user_id_2",
    "..."
  ],
  "requester": "employee@yourcompany.com"
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json'

};

fetch('https://amplitude.com/api/2/deletions/users',
{
  method: 'POST',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'application/json',
  'Accept' => 'application/json'
}

result = RestClient.post 'https://amplitude.com/api/2/deletions/users',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

r = requests.post('https://amplitude.com/api/2/deletions/users', params={

}, headers = headers)

print r.json()

URL obj = new URL("https://amplitude.com/api/2/deletions/users");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("POST");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Content-Type": []string{"application/json"},
        "Accept": []string{"application/json"},

    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("POST", "https://amplitude.com/api/2/deletions/users", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

POST /deletions/users

Delete a user

Request a user be scheduled for deletion, up to 100 users can be specified at a time. A mix of amplitude ids and user ids is permitted.

Body parameter

{
  "amplitude_ids": [
    "amp_id_1",
    "amp_id_2",
    "..."
  ],
  "user_ids": [
    "user_id_1",
    "user_id_2",
    "..."
  ],
  "requester": "employee@yourcompany.com"
}

Parameters

Parameter In Type Required Description
body body DeletionRequest true Deletion request object listing user_ids and amplitude_ids that need to be deleted

Example responses

200 Response

{
  "day": "string",
  "amplitude_ids": [
    {
      "amplitude_id": 0,
      "requested_on_day": "string",
      "requester": "string"
    }
  ],
  "status": "string"
}

Responses

Status Meaning Description Schema
200 OK Success DeletionJob
400 Bad Request Invalid input None

List deletion jobs

Code samples

# You can also use wget
curl -X GET https://amplitude.com/api/2/deletions/users?start=string&end=string \
  -H 'Accept: application/json'

GET https://amplitude.com/api/2/deletions/users?start=string&end=string HTTP/1.1
Host: amplitude.com

Accept: application/json

var headers = {
  'Accept':'application/json'

};

$.ajax({
  url: 'https://amplitude.com/api/2/deletions/users',
  method: 'get',
  data: '?start=string&end=string',
  headers: headers,
  success: function(data) {
    console.log(JSON.stringify(data));
  }
})

const request = require('node-fetch');

const headers = {
  'Accept':'application/json'

};

fetch('https://amplitude.com/api/2/deletions/users?start=string&end=string',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json'
}

result = RestClient.get 'https://amplitude.com/api/2/deletions/users',
  params: {
  'start' => 'string',
'end' => 'string'
}, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json'
}

r = requests.get('https://amplitude.com/api/2/deletions/users', params={
  'start': 'string',  'end': 'string'
}, headers = headers)

print r.json()

URL obj = new URL("https://amplitude.com/api/2/deletions/users?start=string&end=string");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/json"},

    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "https://amplitude.com/api/2/deletions/users", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

GET /deletions/users

List deletion jobs

Get a summary of a user deletion jobs scheduled in a time range

Parameters

Parameter In Type Required Description
start query string true Start day to query for deletion jobs (YYYY-MM-DD)
end query string true End day to query for deletion jobs (YYYY-MM-DD)

Example responses

200 Response

[
  {
    "day": "string",
    "amplitude_ids": [
      {
        "amplitude_id": 0,
        "requested_on_day": "string",
        "requester": "string"
      }
    ],
    "status": "string"
  }
]

Responses

Status Meaning Description Schema
200 OK Success Inline
400 Bad Request Invalid input None

Response Schema

Status Code 200

Name Type Required Restrictions Description
anonymous [DeletionJob] false none none
» day string true none none
» amplitude_ids [AmplitudeId] true none none
»» amplitude_id integer true none none
»» requested_on_day string true none none
»» requester string true none none
» status string true none none

DeletionRequest

{
  "amplitude_ids": [
    "amp_id_1",
    "amp_id_2",
    "..."
  ],
  "user_ids": [
    "user_id_1",
    "user_id_2",
    "..."
  ],
  "requester": "employee@yourcompany.com"
}

Properties

Name Type Required Restrictions Description
amplitude_ids [integer] false none List of amplitude ids that should be deleted
user_ids [string] false none List of user ids that should be deleted
requester string true none Who made this request, for your own tracking/auditing

DeletionJob

{
  "day": "string",
  "amplitude_ids": [
    {
      "amplitude_id": 0,
      "requested_on_day": "string",
      "requester": "string"
    }
  ],
  "status": "string"
}

Properties

Name Type Required Restrictions Description
day string true none none
amplitude_ids [AmplitudeId] true none none
status string true none none

AmplitudeId

{
  "amplitude_id": 0,
  "requested_on_day": "string",
  "requester": "string"
}

Properties

Name Type Required Restrictions Description
amplitude_id integer true none none
requested_on_day string true none none
requester string true none none