# JavaScript SDK APIs

<p>The JavaScript SDK provides a comprehensive API that lets you track and send your event data to any destination.</p>
<!-- end-chunk -->
<!-- begin-chunk -->
<h2 id="pre-load-api-buffering">Pre-load API buffering</h2><p>If you call a supported API before a valid <code>load</code> completes, the SDK keeps that call in an in-memory buffer. This can happen while the CDN snippet loads asynchronously or when you call methods on an imported SDK instance before <code>load</code>.</p>
<p>After a valid <code>load</code>, the SDK initializes with the write key, data plane URL, and load options, then replays the buffered calls in order. For CDN-buffered calls, it replays <code>consent</code> calls first so consent state is available, then replays the remaining calls. If <code>load</code> is invalid, the SDK doesn&rsquo;t replay the buffered calls until a valid load occurs.</p>
<p>The CDN snippet buffers the following APIs:</p>
<ul>
<li>Initialization and lifecycle APIs: <code>setDefaultInstanceKey</code>, <code>load</code>, and <code>ready</code>.</li>
<li>Event APIs: <code>page</code>, <code>track</code>, <code>identify</code>, <code>alias</code>, and <code>group</code>.</li>
<li>State and session APIs: <code>reset</code>, <code>setAnonymousId</code>, <code>startSession</code>, and <code>endSession</code>.</li>
<li>Consent and integration APIs: <code>consent</code> and <code>addCustomIntegration</code>.</li>
<li>Custom context APIs: <code>setCustomContext</code> and <code>clearCustomContext</code>.</li>
</ul>

<html lang="en">
<blockquote class="info">
  <div class="tip-quote">
    
    <div class="tip-text">Pre-load API buffering is different from event delivery queues such as <a href="https://www.rudderstack.com/docs/sources/event-streams/sdks/rudderstack-javascript-sdk/load-js-sdk/#queueopts" ><code>queueOpts</code></a>, <a href="https://www.rudderstack.com/docs/sources/event-streams/sdks/rudderstack-javascript-sdk/load-js-sdk/#send-events-using-beacon" ><code>beaconQueueOptions</code></a>, and pre-consent event buffering. Pre-load API buffering only preserves supported method calls until the SDK is loaded.</div>
  </div>
</blockquote>

</html>
<!-- end-chunk -->
<!-- begin-chunk -->
<h2 id="identify">Identify</h2><p>The <code>identify</code> API lets you identify a user and associate them to their actions. It also lets you record any traits about them like their name, email, etc.</p>
<p>Once you make the <code>identify</code> call, the SDK persists the user information and passes it to the subsequent calls.</p>

<html lang="en">
<blockquote class="info">
  <div class="tip-quote">
    
    <div class="tip-text"><p>The subsequent <code>identify</code> calls with the same <code>userId</code> deeply merge (values are merged recursively, exhausting the entire hierarchy tree) the new user traits with the previously persisted traits.</p>
<p>See <a href="#update-user-traits" >Update user traits</a> section for more information.</p>
</div>
  </div>
</blockquote>

</html>
<p>The <code>identify</code> method definition is as follows:</p>
<div class="rs-tabs">
	<div class="rs-tabs__list">
		<button type="button" class="rs-tabs__tab"
			id="tab-afdcbe"
		
		>Default invocation</button>
		<button type="button" class="rs-tabs__tab"
			id="tab-bcafde"
		
		>Alternate invocations</button>
	</div>
	
<div class="rs-tabs__panel" id="panel-afdcbe">

<div class="rs-code">
  <div class="rs-code__head">javascript<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript">rudderanalytics.identify(userId, [traits], [apiOptions], [callback]);</code></pre></div>
</div>

</div>

<div class="rs-tabs__panel" id="panel-bcafde" hidden>

<div class="rs-code">
  <div class="rs-code__head">javascript<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript">// Identify call with user ID, traits, and callback
rudderanalytics.identify(userId, [traits], [callback]);

// Identify call with user ID and callback
rudderanalytics.identify(userId, [callback]);

// Identify call with user traits, apiOptions, and callback
rudderanalytics.identify(traits, [apiOptions], [callback]);

// Identify call with user traits and callback
rudderanalytics.identify(traits, [callback]);</code></pre></div>
</div>

</div>

</div>

<p>The following table describes the above parameters in detail:</p>
<table>
  <thead>
      <tr>
          <th>Parameter</th>
          <th>Type</th>
          <th><div>Name</div></th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>userId</code></td>
          <td>String</td>
          <td>The unique user identifier. When provided, RudderStack prefers this over <code>anonymousId</code> while sending data to the destinations.</td>
      </tr>
      <tr>
          <td><code>traits</code></td>
          <td>Dictionary</td>
          <td>Contains the user&rsquo;s traits or the properties associated with <code>userId</code> such as email, address, etc. See <a href="https://www.rudderstack.com/docs/event-spec/standard-events/identify/#identify-traits" >Identify traits</a> for more information. <br /><br />Note that: <br /><br /><ul><li>RudderStack stores the traits as <code>context.traits</code> in the final event object.</li><li> If you do not want to send the user traits, pass an empty object (<code>{}</code>) instead.</li></ul></td>
      </tr>
      <tr>
          <td><code>apiOptions</code></td>
          <td>Dictionary</td>
          <td>Option to override <code>integrations</code>, <code>anonymousId</code>, and <code>originalTimestamp</code> fields. Any other keys are merged into the event&rsquo;s <code>context</code> object. <br /><br />See <a href="#apioptions" ><code>apiOptions</code></a> section for more details.</td>
      </tr>
      <tr>
          <td><code>callback</code></td>
          <td>Function</td>
          <td>Invoked after successfully processing and queueing the event data for delivery. It <strong>does not</strong> indicate the actual event delivery but ensures that the SDK makes a delivery attempt.</td>
      </tr>
  </tbody>
</table>
<p>A sample <code>identify</code> call is shown below:</p>
<div class="rs-code">
  <div class="rs-code__head">javascript<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript">rudderanalytics.identify(
  &#34;1hKOmRA4GRlm&#34;, {
    firstName: &#34;Alex&#34;,
    lastName: &#34;Keener&#34;,
    email: &#34;alex@example.com&#34;,
    phone: &#34;+1-202-555-0146&#34;
  }, {
    environment: &#34;production&#34;
  },
  () =&gt; {
    console.log(&#34;Identify event successfully submitted to the RudderStack SDK.&#34;);
  }
);</code></pre></div>
</div>
<p>In the above example, the JavaScript SDK captures the <code>userId</code> along with <code>firstName</code>, <code>lastName</code>, <code>email</code>, and <code>phone</code> as traits and <code>environment</code> as the contextual information along with other automatically-captured <a href="https://www.rudderstack.com/docs/event-spec/standard-events/common-fields/#contextual-fields" >contextual fields</a>.</p>
<!-- end-chunk -->
<!-- begin-chunk -->
<h3 id="anonymous-user-id">Anonymous user ID</h3><p>The <code>anonymousId</code> is an auto-generated <strong>UUID</strong> (Universally Unique Identifier) that gets assigned to each unique and unidentified visitor to your website.</p>
<!-- end-chunk -->
<!-- begin-chunk -->
<h4 id="retrieve-anonymous-user-id">Retrieve anonymous user ID</h4><p>Run the following snippet to retrieve the anonymous ID of any visitor:</p>
<div class="rs-code">
  <div class="rs-code__head">javascript<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript">rudderanalytics.getAnonymousId();</code></pre></div>
</div>

<html lang="en">
<blockquote class="info">
  <div class="tip-quote">
    
    <div class="tip-text">The SDK always ensures that a valid anonymous user ID is returned by the <code>getAnonymousId</code> API. If required, it even auto-generates and sets a new value. For example, if the <code>anonymousId</code> is <code>null</code> and you call the <code>getAnonymousId</code> function, then the SDK automatically sets a new value for <code>anonymousId</code>.</div>
  </div>
</blockquote>

</html>
<!-- end-chunk -->
<!-- begin-chunk -->
<h4 id="how-sdk-uses-anonymous-user-id">How SDK uses anonymous user ID</h4><p>The JavaScript SDK generates a unique <code>anonymousId</code>, stores it in the <code>rl_anonymous_id</code> cookie in the top-level domain by default, and attaches it to every subsequent event. This helps in sharing the identity of the anonymous users across the parent domain and all the sub-domain sites.</p>

<html lang="en">
<blockquote class="info">
  <div class="tip-quote">
    
    <div class="tip-text">If you identify a user with your application&rsquo;s unique identifier like email, database ID, etc., RudderStack stores this ID in the <code>rl_user_id</code> cookie and attaches it to every event.</div>
  </div>
</blockquote>

</html>
<p>Refer to the <a href="https://www.rudderstack.com/docs/sources/event-streams/sdks/rudderstack-javascript-sdk/data-storage-cookies/" >Data Storage</a> guide for more information on how the JavaScript SDK stores persistent user data in cookies.</p>
<!-- end-chunk -->
<!-- begin-chunk -->
<h4 id="override-anonymous-user-id">Override anonymous user ID</h4><p>You can use any of the following three methods to override the <code>anonymousId</code> generated by the JavaScript SDK:</p>
<ul>
<li>Set the <code>anonymousId</code> for all future events using the <code>setAnonymousId()</code> method. An example is shown below:</li>
</ul>
<div class="rs-code">
  <div class="rs-code__head">javascript<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript">rudderanalytics.setAnonymousId(&#34;my-anonymous-id&#34;);
// All event payloads will have the anonymousId key set &#34;my-anonymous-id&#34;.
rudderanalytics.identify(&#34;1hKOmRA4el9Zt1WSfVJIVo4GRlm&#34;, {
  email1: &#34;alex@example.com&#34;
}, () =&gt; {
  console.log(&#34;Identify event successfully submitted to the RudderStack SDK.&#34;);
});</code></pre></div>
</div>
<ul>
<li>Parse the AMP Linker ID and set the <code>anonymousId</code> using AMP Analytics:</li>
</ul>
<div class="rs-code">
  <div class="rs-code__head">javascript<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript">rudderanalytics.setAnonymousId(
  null,
  &#34;&lt;version&gt;*&lt;checkSum&gt;*&lt;idName1&gt;*&lt;idValue1&gt;*&lt;idName2&gt;*&lt;idValue2&gt;...&#34;
);</code></pre></div>
</div>
<p>Here, the second parameter is the AMP Linker ID format in the <a href="https://github.com/ampproject/amphtml/blob/master/extensions/amp-analytics/linker-id-receiving.md#format" >specified structure</a>.  For websites using the <a href="https://www.rudderstack.com/docs/sources/event-streams/sdks/rudderstack-amp-analytics/#amp-linker" >RudderStack AMP Analytics SDK</a>, the <code>&lt;idName1&gt;</code> value will be <code>rs_amp_id</code>.</p>
<p>Calling the above method will parse the Linker ID and set the <code>rs_amp_id</code> key value as the <code>anonymousId</code>.</p>
<ul>
<li>Provide <code>anonymousId</code> in the <a href="#apioptions" ><code>apiOptions</code></a> parameter of the <code>identify</code> call.</li>
</ul>

<html lang="en">
<blockquote class="info">
  <div class="tip-quote">
    
    <div class="tip-text">Note that all other events will have the <code>anonymousId</code> persisted from the cookie except the particular event where you override the <code>apiOptions</code> parameter.</div>
  </div>
</blockquote>

</html>
<p>An example is shown below:</p>
<div class="rs-code">
  <div class="rs-code__head">javascript<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript">rudderanalytics.identify(
  &#34;1hKOmRA4el9Zt1WSfVJIVo4GRlm&#34;, {
    email: &#34;alex@example.com&#34;
  }, {
    anonymousId: &#34;my-anonymous-id&#34;
  },
  () =&gt; {
    console.log(&#34;Identify event successfully submitted to the RudderStack SDK.&#34;);
  }
);</code></pre></div>
</div>
<!-- end-chunk -->
<!-- begin-chunk -->
<h3 id="set-a-blank-user-id">Set a blank user ID</h3><p>To set a blank user ID, you can pass an empty string as the <code>userId</code> parameter in the <code>identify</code> API call.</p>
<p>Note that setting an empty string as the <code>userId</code> only clears the user ID unlike the <a href="#reset" ><code>reset</code></a> API (that also clears the persisted values, for example, user traits).</p>

<blockquote class="warning">
  <div class="tip-quote">
    
    <div class="tip-text">Do not set the <code>userId</code> value to <code>null</code> to reset its value in the SDK.</div>
  </div>
</blockquote>
<!-- end-chunk -->
<!-- begin-chunk -->
<h4 id="use-case">Use case</h4><p>Suppose an anonymous user is identified with a <code>userId</code> and then logs out of their account. You can then call <code>identify(&quot;&quot;, {isLoggedIn: false})</code> and the user will continue to be identified by their <code>anonymousId</code> for the future events.</p>
<!-- end-chunk -->
<!-- begin-chunk -->
<h3 id="identify-new-users">Identify new users</h3><p>You can use any of the below approaches to identify new users in scenarios like new logins:</p>
<ul>
<li>Call <code>identify</code> with a new <code>userId</code></li>
<li>Call <code>reset</code> followed by the <code>identify</code></li>
</ul>
<p>RudderStack resets all cookies related to the user (associated with the <code>userId</code> and <code>traits</code>) and updates them with the newly provided values.</p>

<html lang="en">
<blockquote class="info">
  <div class="tip-quote">
    
    <div class="tip-text">The <code>anonymousId</code> remains unchanged in this case. It will be the auto-generated value set by the SDK or the one explicitly set using the <a href="#override-anonymous-user-id" ><code>setAnonymousId</code></a> method.</div>
  </div>
</blockquote>

</html>
<!-- end-chunk -->
<!-- begin-chunk -->
<h3 id="update-user-traits">Update user traits</h3><p>For updating the user traits, you can call <code>identify</code> method with the same <code>userId</code> multiple times with the new traits. This will append or modify all traits associated with that user. See <a href="#how-sdk-merges-traits" >How SDK merges traits</a> section for more information.</p>
<p>An example is shown below:</p>
<div class="rs-code">
  <div class="rs-code__head">javascript<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript">rudderanalytics.identify(&#34;1hKOmRA4GRlm&#34;, {
    email1: &#34;alex@example.com&#34;
}, () =&gt; {
    console.log(&#34;Identify event successfully submitted to the RudderStack SDK.&#34;);
});

rudderanalytics.identify(&#34;1hKOmRA4GRlm&#34;, {
    email2: &#34;john@example.com&#34;
}, () =&gt; {
    console.log(&#34;Identify event successfully submitted to the RudderStack SDK.&#34;);
});</code></pre></div>
</div>
<p>In the above example, both <code>email1</code> and <code>email2</code> will be sent in the payload for the second <code>identify</code> call, as shown:</p>
<div class="rs-code">
  <div class="rs-code__head">json<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-json" data-lang="json">{
  &#34;userId&#34;: &#34;1hKOmRA4GRlm&#34;,
  &#34;email1&#34;: &#34;alex@example.com&#34;,
  &#34;email2&#34;: &#34;john@example.com&#34;,
    &#34;library&#34;: {
        &#34;name&#34;: &#34;http&#34;
    },
  &#34;timestamp&#34;: &#34;2020-02-02T00:23:09.544Z&#34;
}</code></pre></div>
</div>
<!-- end-chunk -->
<!-- begin-chunk -->
<h4 id="how-the-sdk-merges-traits">How the SDK merges traits</h4><p>While updating user traits via the <code>identify</code> API, the SDK deeply merges (values are merged recursively, exhausting the entire hierarchy tree) the new user traits with the existing traits.</p>
<p>Note the following:</p>
<ul>
<li>
<p><strong>Missing properties</strong>: The SDK adds any properties present in one object but missing in the other to the resulting object.</p>
</li>
<li>
<p><strong>Shared properties</strong>: If both the objects contain the same properties, then:</p>
<ul>
<li>If both the properties are <strong>objects</strong>, then their contents are merged recursively.</li>
<li>If both the properties are <strong>arrays</strong>, then values from the right-side array will replace those in the left-side array at the same position. <strong>Note this could result in duplicate values in the array</strong>.</li>
<li>If the data types of the shared properties <strong>do not match</strong>, then the value from the right-side object will take precedence, overwriting the left-side value.</li>
</ul>
</li>
</ul>
<!-- end-chunk -->
<!-- begin-chunk -->
<h4 id="reset-user-traits-vs-update-user-traits">Reset user traits vs. update user traits</h4><p>Note that the <code>reset</code> API and <code>identify</code> API handle user traits differently.</p>
<!-- end-chunk -->
<!-- begin-chunk -->
<h5 id="reset-user-traits"><strong>Reset user traits</strong></h5><p>You can use the <a href="#reset" ><code>reset</code> API</a> to selectively reset user traits as per your requirement.</p>
<ul>
<li>To reset all user traits, call <code>reset()</code> or explicitly set the <code>userTraits</code> parameter of the <code>entries</code> object to <code>true</code>:</li>
</ul>
<div class="rs-code">
  <div class="rs-code__head">javascript<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript">// Reset all user traits (along with other default entries)
rudderanalytics.reset();

// Or explicitly specify
rudderanalytics.reset({
  entries: {
    userTraits: true
  }
});</code></pre></div>
</div>
<ul>
<li>To reset only user traits while preserving all other data:</li>
</ul>
<div class="rs-code">
  <div class="rs-code__head">javascript<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript">// Reset only user traits, preserve all other persisted information

rudderanalytics.reset({
  entries: {
    sessionInfo: false,
    userId: false,
    userTraits: true,
    groupId: false,
    groupTraits: false,
    authToken: false
  }
});</code></pre></div>
</div>
<p>See the <a href="#reset" >Reset API</a> section for more details.</p>
<!-- end-chunk -->
<!-- begin-chunk -->
<h5 id="update-user-traits-1"><strong>Update user traits</strong></h5><p>You can call the <code>identify</code> API with new traits to update the existing user traits, as shown:</p>
<div class="rs-code">
  <div class="rs-code__head">javascript<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript">rudderanalytics.identify(&#34;1hKOmRA4GRlm&#34;, {
  email: &#34;alex@example.com&#34;
}, () =&gt; {
  console.log(&#34;Identify event successfully submitted to the RudderStack SDK.&#34;);
});

rudderanalytics.identify({
  email: &#34;alice@example.com&#34;
}, () =&gt; {
  console.log(&#34;Identify event successfully submitted to the RudderStack SDK.&#34;);
});</code></pre></div>
</div>
<p>In this case, the SDK updates the <code>email</code> field from <code>alex@example.com</code> to <code>alice@example.com</code>.</p>
<!-- end-chunk -->
<!-- begin-chunk -->
<h2 id="page">Page</h2><p>The <code>page</code> API lets you record your website&rsquo;s page views with any additional relevant information about the viewed page. Many destinations require the <code>page</code> call to be made at least once every page load.</p>
<p>The <code>page</code> method definition is as follows:</p>
<div class="rs-tabs">
	<div class="rs-tabs__list">
		<button type="button" class="rs-tabs__tab"
			id="tab-adfbce"
		
		>Default invocation</button>
		<button type="button" class="rs-tabs__tab"
			id="tab-facedb"
		
		>Alternate invocations</button>
	</div>
	
<div class="rs-tabs__panel" id="panel-adfbce">

<div class="rs-code">
  <div class="rs-code__head">javascript<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript">rudderanalytics.page([category], [name], [properties], [apiOptions], [callback]);</code></pre></div>
</div>

</div>

<div class="rs-tabs__panel" id="panel-facedb" hidden>

<div class="rs-code">
  <div class="rs-code__head">javascript<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript">// Page call with page category, name, properties, options, and callback
rudderanalytics.page(category, name, [properties], [apiOptions], [callback]);

// Page call with page category, name, properties, and callback
rudderanalytics.page(category, name, [properties], [callback]);

// Page call with page category, name, and callback
rudderanalytics.page(category, name, [callback]);

// Page call with page name, properties, options, and callback
rudderanalytics.page(name, [properties], [apiOptions], [callback]);

// Page call with page name, properties, and callback
rudderanalytics.page(name, [properties], [callback]);

// Page call with page name and callback
rudderanalytics.page(name, [callback]);

// Page call with page properties, options, and callback
rudderanalytics.page(properties, [apiOptions], [callback]);

// Page call with page properties, and callback
rudderanalytics.page(properties, [callback]);

// Page call with callback
rudderanalytics.page([callback]);</code></pre></div>
</div>

</div>

</div>

<p>The following table describes the above (optional) parameters in detail:</p>
<table>
  <thead>
      <tr>
          <th>Parameter</th>
          <th>Type</th>
          <th>Description</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>category</code></td>
          <td>String</td>
          <td>Category of the page.</td>
      </tr>
      <tr>
          <td><code>name</code></td>
          <td>String</td>
          <td>Name of the page.</td>
      </tr>
      <tr>
          <td><code>properties</code></td>
          <td>Dictionary</td>
          <td>The page properties. The SDK auto-captures the page <code>path</code>, <code>url</code>, <code>referrer</code>, <code>search</code>, and <code>title</code> fields if not explicitly provided in the <code>page</code> API. <br /><br /><strong>Note</strong>: If you do not want to send the page properties, pass an empty object (<code>{}</code>) instead.</td>
      </tr>
      <tr>
          <td><code>apiOptions</code></td>
          <td>Dictionary</td>
          <td>Provides information such as <code>integrations</code>, <code>anonymousId</code>, and <code>originalTimestamp</code>.  <a href="#apioptions" >Reference</a>.</td>
      </tr>
      <tr>
          <td><code>callback</code></td>
          <td>Function</td>
          <td>Invoked after successfully processing and queueing the event data for delivery. It <strong>does not</strong> indicate the actual event delivery but ensures that the SDK makes a delivery attempt.</td>
      </tr>
  </tbody>
</table>
<p>A sample <code>page</code> call is shown below:</p>
<div class="rs-code">
  <div class="rs-code__head">javascript<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript">rudderanalytics.page(
  &#34;Cart&#34;,
  &#34;Cart Viewed&#34;, {
    environment: &#34;production&#34;
  }, {
    integrations: {
      All: false,
      Amplitude: true
    }
  }
  () =&gt; {
    console.log(&#34;Page event successfully submitted to the RudderStack SDK.&#34;);
  }
);</code></pre></div>
</div>
<p>In the above example, the JavaScript SDK captures the page <code>category</code> and <code>name</code> along with the <a href="https://www.rudderstack.com/docs/event-spec/standard-events/common-fields/#contextual-fields" >contextual information</a>, and sends the event <strong>only</strong> to the Amplitude destination.</p>
<!-- end-chunk -->
<!-- begin-chunk -->
<h2 id="track">Track</h2><p>The <code>track</code> API lets you capture user events along with the associated properties.</p>
<p>The <code>track</code> method definition is as follows:</p>
<div class="rs-tabs">
	<div class="rs-tabs__list">
		<button type="button" class="rs-tabs__tab"
			id="tab-acbdfe"
		
		>Default invocation</button>
		<button type="button" class="rs-tabs__tab"
			id="tab-bfacde"
		
		>Alternate invocations</button>
	</div>
	
<div class="rs-tabs__panel" id="panel-acbdfe">

<div class="rs-code">
  <div class="rs-code__head">javascript<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript">rudderanalytics.track(event, [properties], [apiOptions], [callback]);</code></pre></div>
</div>

</div>

<div class="rs-tabs__panel" id="panel-bfacde" hidden>

<div class="rs-code">
  <div class="rs-code__head">javascript<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript">// Track call with event, properties, and callback
rudderanalytics.track(event, [properties], [callback]);

// Track call with event and callback
rudderanalytics.track(event, [callback]);</code></pre></div>
</div>

</div>

</div>

<p>The following table describes the above parameters in detail:</p>
<table>
  <thead>
      <tr>
          <th>Parameter</th>
          <th>Type</th>
          <th>Description</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>event</code></td>
          <td>String</td>
          <td>The name of the tracked event.</td>
      </tr>
      <tr>
          <td><code>properties</code></td>
          <td>Dictionary</td>
          <td>The event-related properties. <br /><br /><strong>Note</strong>: If you do not want to send the properties, pass an empty object (<code>{}</code>) instead.</td>
      </tr>
      <tr>
          <td><code>apiOptions</code></td>
          <td>Dictionary</td>
          <td>Provides information such as <code>integrations</code>, <code>anonymousId</code>, and <code>originalTimestamp</code>. <a href="#apioptions" >Reference</a>.</td>
      </tr>
      <tr>
          <td><code>callback</code></td>
          <td>Function</td>
          <td>Invoked after successfully processing and queueing the event data for delivery. It <strong>does not</strong> indicate the actual event delivery but ensures that the SDK makes a delivery attempt.</td>
      </tr>
  </tbody>
</table>
<p>A sample <code>track</code> call is shown below:</p>
<div class="rs-code">
  <div class="rs-code__head">javascript<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript">rudderanalytics.track(
  &#34;Order Completed&#34;, {
    revenue: 30,
    currency: &#34;USD&#34;,
    user_actual_id: 12345
  },
  () =&gt; {
    console.log(&#34;Track event successfully submitted to the RudderStack SDK.&#34;);
  }
);</code></pre></div>
</div>
<p>In the above example, the <code>track</code> method tracks the <code>Order Completed</code> event along with other information like <code>revenue</code>, <code>currency</code>, and the <code>user_actual_id</code>.</p>
<p>Refer to the <a href="https://www.rudderstack.com/docs/event-spec/ecommerce-events-spec/" >Ecommerce Events Specification</a> for more information on the ecommerce events captured by RudderStack.</p>
<!-- end-chunk -->
<!-- begin-chunk -->
<h2 id="group">Group</h2><p>The <code>group</code> API lets you associate an identified user with a group such as a company, organization, or an account.</p>

<blockquote class="warning">
  <div class="tip-quote">
    
    <div class="tip-text">RudderStack does not support associating a user to more than one group in a single <code>group</code> API call.</div>
  </div>
</blockquote>
<p>The <code>group</code> method definition is as follows:</p>
<div class="rs-tabs">
	<div class="rs-tabs__list">
		<button type="button" class="rs-tabs__tab"
			id="tab-edcafb"
		
		>Default invocation</button>
		<button type="button" class="rs-tabs__tab"
			id="tab-decfab"
		
		>Alternate invocations</button>
	</div>
	
<div class="rs-tabs__panel" id="panel-edcafb">

<div class="rs-code">
  <div class="rs-code__head">javascript<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript">rudderanalytics.group(groupId, [traits], [apiOptions], [callback]);</code></pre></div>
</div>

</div>

<div class="rs-tabs__panel" id="panel-decfab" hidden>

<div class="rs-code">
  <div class="rs-code__head">javascript<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript">// Group call with group ID, traits, and callback
rudderanalytics.group(groupId, [traits], [callback]);

// Group call with group ID and callback
rudderanalytics.group(groupId, [callback]);

// Group call with traits, apiOptions, and callback
rudderanalytics.group(traits, [apiOptions], [callback]);

// Group call with traits and callback
rudderanalytics.group(traits, [callback]);</code></pre></div>
</div>

</div>

</div>

<p>The following table describes the above parameters in detail:</p>
<table>
  <thead>
      <tr>
          <th>Parameter</th>
          <th>Type</th>
          <th>Description</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>groupId</code></td>
          <td>String</td>
          <td>The unique group identifier in the database. RudderStack calls the relevant destination APIs to associate the identified user to this group.</td>
      </tr>
      <tr>
          <td><code>traits</code></td>
          <td>Dictionary</td>
          <td>The group-related traits. RudderStack passes these traits to the destination to enhance the group properties. <br /><br />Note that: <br /><br /><ul><li>RudderStack stores the group traits at the root level as <code>traits</code> object in the final event object.</li><li> If you do not want to send the group traits, pass an empty object (<code>{}</code>) instead.</li></ul></td>
      </tr>
      <tr>
          <td><code>apiOptions</code></td>
          <td>Dictionary</td>
          <td>Provides information such as <code>integrations</code>, <code>anonymousId</code>, and <code>originalTimestamp</code>. <a href="#apioptions" >Reference</a>.</td>
      </tr>
      <tr>
          <td><code>callback</code></td>
          <td>Function</td>
          <td>Invoked after successfully processing and queueing the event data for delivery. It <strong>does not</strong> indicate the actual event delivery but ensures that the SDK makes a delivery attempt.</td>
      </tr>
  </tbody>
</table>
<p>A sample <code>group</code> call is shown:</p>
<div class="rs-code">
  <div class="rs-code__head">javascript<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript">rudderanalytics.group(&#34;grp114412&#34;, {
  name: &#34;Apple Inc.&#34;,
  location: &#34;USA&#34;,
});</code></pre></div>
</div>
<!-- end-chunk -->
<!-- begin-chunk -->
<h3 id="update-group-traits">Update group traits</h3><p>For updating the group traits, you can call <code>group</code> method with the same <code>groupId</code> multiple times along with the new traits. This appends or modifies all traits associated with that group. See <a href="#how-sdk-merges-group-traits" >How SDK merges group traits</a> section for more information.</p>
<p>An example is shown below:</p>
<div class="rs-code">
  <div class="rs-code__head">javascript<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript">rudderanalytics.group(&#34;grp114412&#34;, {
  name1: &#34;Group A&#34;
}, () =&gt; {
    console.log(&#34;Group event successfully submitted to the RudderStack SDK.&#34;);
});

rudderanalytics.group(&#34;grp114412&#34;, {
    name2: &#34;Group B&#34;
}, () =&gt; {
    console.log(&#34;Group event successfully submitted to the RudderStack SDK.&#34;);
});</code></pre></div>
</div>
<p>In the above example, both <code>name1</code> and <code>name2</code> will be sent in the payload for the second <code>group</code> call, as shown:</p>
<div class="rs-code">
  <div class="rs-code__head">json<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-json" data-lang="json">{
  &#34;groupId&#34;: &#34;grp114412&#34;,
  &#34;name1&#34;: &#34;Group A&#34;,
  &#34;name2&#34;: &#34;Group B&#34;,
    &#34;library&#34;: {
        &#34;name&#34;: &#34;http&#34;
    },
  &#34;timestamp&#34;: &#34;2020-02-02T00:23:09.544Z&#34;
}</code></pre></div>
</div>
<!-- end-chunk -->
<!-- begin-chunk -->
<h4 id="how-sdk-merges-group-traits">How SDK merges group traits</h4><p>While updating group traits via the <code>group</code> API, the SDK deeply merges (values are merged recursively, exhausting the entire hierarchy tree) the new user traits with the existing traits.</p>
<p>Note the following:</p>
<ul>
<li>
<p><strong>Missing properties</strong>: The SDK adds any properties present in one object but missing in the other to the resulting object.</p>
</li>
<li>
<p><strong>Shared properties</strong>: If both the objects contain the same properties, then:</p>
<ul>
<li>If both the properties are <strong>objects</strong>, then their contents are merged recursively.</li>
<li>If both the properties are <strong>arrays</strong>, then values from the right-side array will replace those in the left-side array at the same position. <strong>Note this could result in duplicate values in the array</strong>.</li>
<li>If the data types of the shared properties <strong>do not match</strong>, then the value from the right-side object will take precedence, overwriting the left-side value.</li>
</ul>
</li>
</ul>
<!-- end-chunk -->
<!-- begin-chunk -->
<h4 id="reset-group-traits-vs-update-group-traits">Reset group traits vs. update group traits</h4><p>The <code>reset</code> API and <code>group</code> API handle group traits differently.</p>
<!-- end-chunk -->
<!-- begin-chunk -->
<h5 id="reset-group-traits"><strong>Reset group traits</strong></h5><p>You can use the <a href="#reset" ><code>reset</code> API</a> to selectively reset group traits as per your requirement.</p>
<ul>
<li>To reset all group traits, call <code>reset()</code> or explicitly set the <code>groupTraits</code> parameter of the <code>entries</code> object to <code>true</code>:</li>
</ul>
<div class="rs-code">
  <div class="rs-code__head">javascript<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript">// Reset all group traits (along with other default entries)
rudderanalytics.reset();

// Or explicitly specify
rudderanalytics.reset({
  entries: {
    groupTraits: true
  }
});</code></pre></div>
</div>
<ul>
<li>To reset only group traits while preserving all other data:</li>
</ul>
<div class="rs-code">
  <div class="rs-code__head">javascript<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript">// Reset only group traits, preserve all other persisted information

rudderanalytics.reset({
  entries: {
    sessionInfo: false,
    userId: false,
    userTraits: false,
    groupId: false,
    groupTraits: true
  }
});</code></pre></div>
</div>
<!-- end-chunk -->
<!-- begin-chunk -->
<h5 id="update-group-traits-1"><strong>Update group traits</strong></h5><p>On the other hand, call the <code>group()</code> API with new traits to <strong>update</strong> the existing group traits, as shown:</p>
<div class="rs-code">
  <div class="rs-code__head">javascript<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript">rudderanalytics.group(&#34;grp114412&#34;, {
  name: &#34;Group A&#34;
}, () =&gt; {
  console.log(&#34;Group event successfully submitted to the RudderStack SDK.&#34;);
});

rudderanalytics.group({
  name: &#34;Group B&#34;
}, () =&gt; {
  console.log(&#34;Group event successfully submitted to the RudderStack SDK.&#34;);
});</code></pre></div>
</div>
<p>In this case, the SDK updates the <code>name</code> field from <code>Group A</code> to <code>Group B</code>.</p>
<!-- end-chunk -->
<!-- begin-chunk -->
<h2 id="alias">Alias</h2><p>The <code>alias</code> API lets you merge different identities of a known user.</p>
<p>The <code>alias</code> method definition is as follows:</p>
<div class="rs-tabs">
	<div class="rs-tabs__list">
		<button type="button" class="rs-tabs__tab"
			id="tab-cdfbae"
		
		>Default invocation</button>
		<button type="button" class="rs-tabs__tab"
			id="tab-abefcd"
		
		>Alternate invocations</button>
	</div>
	
<div class="rs-tabs__panel" id="panel-cdfbae">

<div class="rs-code">
  <div class="rs-code__head">javascript<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript">rudderanalytics.alias(to, [from], [apiOptions], [callback]);</code></pre></div>
</div>

</div>

<div class="rs-tabs__panel" id="panel-abefcd" hidden>

<div class="rs-code">
  <div class="rs-code__head">javascript<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript">// Alias call with new and old user identifier and callback
rudderanalytics.alias(to, [from], [callback]);

// Alias call with new user identifier, apiOptions, and callback
rudderanalytics.alias(to, [apiOptions], [callback]);

// Alias call with new user identifier and callback
rudderanalytics.alias(to, [callback]);</code></pre></div>
</div>

</div>

</div>

<p>The following table describes the above parameters in detail:</p>
<table>
  <thead>
      <tr>
          <th>Parameter</th>
          <th>Type</th>
          <th>Description</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>to</code></td>
          <td>String</td>
          <td>New user identifier (<code>userId</code>) associated with the user. <br /><br /><strong>Note</strong>: Subsequent events will still have the previous identifier as the <code>userId</code> field.</td>
      </tr>
      <tr>
          <td><code>from</code></td>
          <td>String</td>
          <td>Old user identifier which will be an alias for the <code>to</code> parameter. If not provided, the SDK populates this as the currently identified <code>userId</code>, or <code>anonymousId</code> in case of anonymous users.</td>
      </tr>
      <tr>
          <td><code>apiOptions</code></td>
          <td>Dictionary</td>
          <td>Provides information such as <code>integrations</code>, <code>anonymousId</code>, and <code>originalTimestamp</code>. <a href="#apioptions" >Reference</a>.</td>
      </tr>
      <tr>
          <td><code>callback</code></td>
          <td>Function</td>
          <td>Invoked after successfully processing and queueing the event data for delivery. It <strong>does not</strong> indicate the actual event delivery but ensures that the SDK makes a delivery attempt.</td>
      </tr>
  </tbody>
</table>
<p>A sample <code>alias</code> call is shown below:</p>
<div class="rs-code">
  <div class="rs-code__head">javascript<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript">rudderanalytics.alias(&#34;new_id&#34;, &#34;old_id&#34;, () =&gt; {
  console.log(&#34;Alias event successfully submitted to the RudderStack SDK.&#34;);
});</code></pre></div>
</div>
<!-- end-chunk -->
<!-- begin-chunk -->
<h2 id="reset">Reset</h2><p>The <code>reset</code> API lets you clear the persisted user session data.</p>
<p>Note that:</p>
<ul>
<li>If <a href="https://www.rudderstack.com/docs/sources/event-streams/sdks/session-tracking/" >session tracking</a> is enabled, calling the <code>reset</code> method also clears the current <code>sessionId</code> and generates a new one.</li>
<li>The <code>reset</code> API only clears the <a href="https://www.rudderstack.com/docs/sources/event-streams/sdks/rudderstack-javascript-sdk/data-storage-cookies/" >user data</a> persisted by RudderStack. It <strong>does not clear</strong> the data stored by the integrated destinations.</li>
<li>The <code>reset</code> API doesn&rsquo;t clear <a href="https://www.rudderstack.com/docs/sources/event-streams/sdks/rudderstack-javascript-sdk/custom-context/" >custom context</a>. Use <code>clearCustomContext()</code> to clear it explicitly.</li>
</ul>
<p>The <code>reset</code> method supports the following invocations:</p>
<div class="rs-code">
  <div class="rs-code__head">javascript<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript">// Reset with selective options (Recommended)
rudderanalytics.reset(options);

// Reset all data except anonymous user ID and initial page referrer information (Default behavior)
rudderanalytics.reset();

// Reset all data (including anonymous user ID) (Deprecated)
rudderanalytics.reset(true);</code></pre></div>
</div>
<!-- end-chunk -->
<!-- begin-chunk -->
<h4 id="the-options-parameter">The <code>options</code> parameter</h4><p>The <code>options</code> parameter of the <code>reset</code> API accepts an object with the following structure:</p>
<div class="rs-code">
  <div class="rs-code__head">javascript<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript">{
  entries: {
    sessionInfo: boolean,                // Default: true
    userId: boolean,                     // Default: true
    userTraits: boolean,                 // Default: true
    groupId: boolean,                    // Default: true
    groupTraits: boolean,                // Default: true
    authToken: boolean,                  // Default: true
    anonymousId: boolean,                // Default: false
    initialReferrer: boolean,            // Default: false
    initialReferringDomain: boolean      // Default: false
  }
}</code></pre></div>
</div>
<p>The following table describes the <code>entries</code> parameters:</p>
<table>
  <thead>
      <tr>
          <th>Parameter</th>
          <th>Description</th>
          <th>Default value</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>sessionInfo</code></td>
          <td>Clears the current session information.</td>
          <td><code>true</code></td>
      </tr>
      <tr>
          <td><code>userId</code></td>
          <td>Clears the persisted user ID.</td>
          <td><code>true</code></td>
      </tr>
      <tr>
          <td><code>userTraits</code></td>
          <td>Clears the persisted user traits.</td>
          <td><code>true</code></td>
      </tr>
      <tr>
          <td><code>groupId</code></td>
          <td>Clears the persisted group ID.</td>
          <td><code>true</code></td>
      </tr>
      <tr>
          <td><code>groupTraits</code></td>
          <td>Clears the persisted group traits.</td>
          <td><code>true</code></td>
      </tr>
      <tr>
          <td><code>authToken</code></td>
          <td>Clears the persisted authentication token.</td>
          <td><code>true</code></td>
      </tr>
      <tr>
          <td><code>anonymousId</code></td>
          <td>Clears and regenerates the anonymous user ID.</td>
          <td><code>false</code></td>
      </tr>
      <tr>
          <td><code>initialReferrer</code></td>
          <td>Clears the persisted initial page referrer information.</td>
          <td><code>false</code></td>
      </tr>
      <tr>
          <td><code>initialReferringDomain</code></td>
          <td>Clears the persisted initial referring domain information.</td>
          <td><code>false</code></td>
      </tr>
  </tbody>
</table>

<html lang="en">
<blockquote class="info">
  <div class="tip-quote">
    
    <div class="tip-text"><p>Note that:</p>
<ul>
<li>All entries in the <code>options.entries</code> object are optional.</li>
<li>If you do not specify any entry, the SDK sets its default value as described in the above table.</li>
</ul></div>
  </div>
</blockquote>

</html>
<!-- end-chunk -->
<!-- begin-chunk -->
<h4 id="examples">Examples</h4><ul>
<li><strong>Default behavior</strong> — Reset all data except <code>anonymousId</code> and initial page referrer information:</li>
</ul>
<div class="rs-code">
  <div class="rs-code__head">javascript<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript">rudderanalytics.reset();</code></pre></div>
</div>
<ul>
<li>Reset all data except session information:</li>
</ul>
<div class="rs-code">
  <div class="rs-code__head">javascript<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript">rudderanalytics.reset({
  entries: {
    sessionInfo: false,
    anonymousId: true,
    initialReferrer: true,
    initialReferringDomain: true
  }
});</code></pre></div>
</div>
<ul>
<li>Reset only session information but preserve all other data:</li>
</ul>
<div class="rs-code">
  <div class="rs-code__head">javascript<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript">rudderanalytics.reset({
  entries: {
    sessionInfo: true,               // Resets session information
    userId: false,
    userTraits: false,
    groupId: false,
    groupTraits: false,
    authToken: false
  }
});</code></pre></div>
</div>
<ul>
<li>Reset all data, including <code>anonymousId</code> and initial page referrer information:</li>
</ul>
<div class="rs-code">
  <div class="rs-code__head">javascript<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript">rudderanalytics.reset({
  entries: {
    anonymousId: true,                // Default: false
    initialReferrer: true,            // Default: false
    initialReferringDomain: true      // Default: false
  }
});</code></pre></div>
</div>
<ul>
<li>Reset only user ID and user traits but preserve all other data:</li>
</ul>
<div class="rs-code">
  <div class="rs-code__head">javascript<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript">rudderanalytics.reset({
  entries: {
    userId: true,
    userTraits: true,
    sessionInfo: false,
    groupId: false,
    groupTraits: false,
    authToken: false
  }
});</code></pre></div>
</div>

<html lang="en">
<blockquote class="info">
  <div class="tip-quote">
    
    <div class="tip-text"><p>Note that <code>rudderanalytics.reset(true)</code> continues to work <strong>but is deprecated</strong>. RudderStack recommends using the following instead:</p>
<div class="rs-code">
  <div class="rs-code__head">javascript<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript">rudderanalytics.reset({
  entries: {
    anonymousId: true
  }
});</code></pre></div>
</div></div>
  </div>
</blockquote>

</html>
<!-- end-chunk -->
<!-- begin-chunk -->
<h2 id="custom-context">Custom context</h2><p>Custom context APIs let you store in-memory context that the JavaScript SDK applies to subsequent <code>track</code>, <code>page</code>, <code>identify</code>, <code>group</code>, and <code>alias</code> calls during the current page load.</p>
<div class="rs-code">
  <div class="rs-code__head">javascript<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript">rudderanalytics.setCustomContext(context);
rudderanalytics.getCustomContext();
rudderanalytics.clearCustomContext();</code></pre></div>
</div>
<table>
  <thead>
      <tr>
          <th>API</th>
          <th>Description</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>setCustomContext(context)</code></td>
          <td>Deep-merges the provided object into the stored custom context.</td>
      </tr>
      <tr>
          <td><code>getCustomContext()</code></td>
          <td>Returns a snapshot of the current custom context.</td>
      </tr>
      <tr>
          <td><code>clearCustomContext()</code></td>
          <td>Clears all stored custom context.</td>
      </tr>
  </tbody>
</table>

<html lang="en">
<blockquote class="info">
  <div class="tip-quote">
    
    <div class="tip-text"><code>setCustomContext</code> and <code>clearCustomContext</code> calls made before SDK load use the SDK&rsquo;s <a href="#pre-load-api-buffering" >pre-load API buffering</a>. <code>getCustomContext()</code> returns an empty object if you call it before SDK load.</div>
  </div>
</blockquote>

</html>
<p>Note that:</p>
<ul>
<li>The <a href="#apioptions" ><code>apiOptions</code></a> passed to a single event — additional keys or a nested <code>context</code> object — override global custom context for that event only and don&rsquo;t mutate the stored custom context.</li>
<li>Calling <code>rudderanalytics.reset()</code> doesn&rsquo;t clear custom context — use <code>clearCustomContext()</code> explicitly.</li>
</ul>
<p>See <a href="https://www.rudderstack.com/docs/sources/event-streams/sdks/rudderstack-javascript-sdk/custom-context/" >Custom Context in JavaScript SDK</a> for the complete custom context reference, including load-time context, deletion semantics, merge precedence, reserved keys, and TypeScript types.</p>
<!-- end-chunk -->
<!-- begin-chunk -->
<h2 id="apioptions"><code>apiOptions</code> parameter</h2><p>You can use the <code>apiOptions</code> parameter to override specific event-level properties and include any additional contextual information.</p>

<blockquote class="warning">
  <div class="tip-quote">
    
    <div class="tip-text">The SDK does not carry forward any of the information contained in <code>apiOptions</code> to the other events.</div>
  </div>
</blockquote>
<p>The structure of the <code>apiOptions</code> parameter is shown:</p>
<div class="rs-code">
  <div class="rs-code__head">javascript<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript">{
  integrations: IntegrationOpts,
  anonymousId: string,
  originalTimestamp: ISO 8601 date string,
  &lt;other keys&gt;: &lt;value&gt; // Additional keys merged with event&#39;s contextual information
}</code></pre></div>
</div>
<p>The following table describes the above parameters in detail:</p>
<table>
  <thead>
      <tr>
          <th>Parameter</th>
          <th>Type</th>
          <th>Description</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>integrations</code></td>
          <td><a href="https://www.rudderstack.com/docs/sources/event-streams/sdks/rudderstack-javascript-sdk/load-js-sdk/#integrationopts" >IntegrationOpts</a></td>
          <td>Sends event data only to the <a href="https://www.rudderstack.com/docs/sources/event-streams/sdks/rudderstack-javascript-sdk/filtering/" >selective destinations</a>.</td>
      </tr>
      <tr>
          <td><code>anonymousId</code></td>
          <td>String</td>
          <td>Overrides the current event&rsquo;s <code>anonymousId</code> at the top level.</td>
      </tr>
      <tr>
          <td><code>originalTimestamp</code></td>
          <td>ISO 8601 Date string</td>
          <td>Overrides the current event&rsquo;s <code>originalTimestamp</code> at the top level. See <a href="https://www.rudderstack.com/docs/event-spec/standard-events/common-fields/#clock-skew-considerations" >Clock skew considerations</a> for more information.</td>
      </tr>
  </tbody>
</table>

<html lang="en">
<blockquote class="info">
  <div class="tip-quote">
    
    <div class="tip-text"><p>Note that:</p>
<ul>
<li>The SDK merges any fields other than the ones mentioned above into the event&rsquo;s <code>context</code> object.</li>
<li>If you specify the IP address in the event&rsquo;s <code>apiOptions</code>, RudderStack uses that instead of <a href="https://www.rudderstack.com/docs/event-spec/standard-events/common-fields/#how-rudderstack-collects-ip-address" >automatically capturing it in the backend</a>. You can use this feature to anonymize your users’ IP addresses.</li>
</ul></div>
  </div>
</blockquote>

</html>
<!-- end-chunk -->
<!-- begin-chunk -->
<h2 id="ready-api">Ready</h2><p>The JavaScript SDK exposes a <code>ready</code> API with a callback parameter that fires when the SDK is fully initialized and ready, including all third-party destination SDKs.</p>
<div class="rs-code">
  <div class="rs-code__head">javascript<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript">rudderanalytics.ready(() =&gt; {
  console.log(&#39;The JavaScript SDK is ready.&#39;);
});</code></pre></div>
</div>
<!-- end-chunk -->
<!-- begin-chunk -->
<h4 id="ready-callback-scenarios"><code>ready</code> callback scenarios</h4><p>There are three main scenarios where the SDK can be considered &ldquo;ready&rdquo;:</p>
<ul>
<li>When all connected integrations are ready</li>
<li>When the SDK times out waiting for some native integrations and moves to the ready state</li>
<li>When using the <a href="https://www.rudderstack.com/docs/sources/event-streams/sdks/rudderstack-javascript-sdk/consent-management/#pre-consent-user-tracking" >pre-consent mode</a></li>
</ul>

<html lang="en">
<blockquote class="info">
  <div class="tip-quote">
    
    <div class="tip-text"><p>You can start instrumenting events immediately after the SDK initialization snippet (for CDN installation) or once the SDK instance is created (for NPM installations). The SDK has built-in mechanisms to buffer events and process them appropriately for delivery to the data plane and device mode destinations, even before it&rsquo;s fully ready.</p>
<p>However, this callback is helpful when you want to:</p>
<ul>
<li><strong>Determine if the SDK is fully ready</strong> by ensuring the SDK and all connected integrations (including device mode destinations) are completely initialized and operational.</li>
<li><strong>Interact with native third-party SDKs directly</strong> in cases where the integration SDKs initialize or create them.</li>
</ul>
</div>
  </div>
</blockquote>

</html>
<!-- end-chunk -->
<!-- begin-chunk -->
<h4 id="difference-between-ready-and-onloaded-callbacks">Difference between <code>ready</code> and <code>onLoaded</code> callbacks</h4>
<blockquote class="warning">
  <div class="tip-quote">
    
    <div class="tip-text"><p>Do not confuse the <code>ready</code> callback with the <code>onLoaded</code> callback — the <code>onLoaded</code> callback fires earlier in the SDK initialization process. It executes after the JavaScript SDK loads but before the device mode destination SDKs are loaded.</p>
<p>See the <a href="https://www.rudderstack.com/docs/sources/event-streams/sdks/rudderstack-javascript-sdk/load-js-sdk/#onloaded" ><code>onLoaded</code> callback documentation</a> for more information.</p>
</div>
  </div>
</blockquote>
<p>The JavaScript SDK provides two different callbacks — <code>ready</code> and <code>onLoaded</code> — both serving distinct purposes:</p>
<table>
  <thead>
      <tr>
          <th>Callback</th>
          <th>Purpose</th>
          <th>When it fires</th>
          <th>Use case</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>ready</code></td>
          <td>Determines if the SDK and all connected integrations are fully ready</td>
          <td>After all device mode destination SDKs are loaded and initialized</td>
          <td>Interact with native third-party SDK instances directly, ensure complete initialization, and no pending items remain.</td>
      </tr>
      <tr>
          <td><code>onLoaded</code></td>
          <td>Indicates the SDK&rsquo;s core modules have finished initializing</td>
          <td>After the SDK loads but before device mode destination SDKs are loaded</td>
          <td>Access core SDK functionality.</td>
      </tr>
  </tbody>
</table>
<!-- end-chunk -->
<!-- begin-chunk -->
<h4 id="rsa_ready-event"><code>RSA_Ready</code> event</h4><p>The JavaScript SDK also supports the <code>RSA_Ready</code> event as an alternative to the <code>ready</code> API to ensure that the SDK is ready. It provides a reference to the analytics instance (<code>analyticsInstance</code>) to invoke any API method and can be used for orchestration with the JavaScript frameworks and libraries.</p>

<blockquote class="success">
  <div class="tip-quote">
    
    <div class="tip-text">
      The <code>RSA_Ready</code> event is useful in cases where the relevant business logic is in functions that cannot be declared alongside the analytics integration or they need to be declared on a decoupled code base.
    </div>
  </div>
</blockquote>
<p>You can listen to the <code>RSA_Ready</code> event as follows:</p>
<div class="rs-code">
  <div class="rs-code__head">html<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-html" data-lang="html">&lt;script&gt;
   document.addEventListener(&#39;RSA_Ready&#39;, function(e) {
     console.log(&#39;RSA_Ready&#39;, e.detail.analyticsInstance);
   })
&lt;/script&gt;</code></pre></div>
</div>
<!-- end-chunk -->
<!-- begin-chunk -->
<h2 id="consent-api">Consent</h2>

<p>You can invoke the JavaScript SDK&rsquo;s <a href="https://www.rudderstack.com/docs/sources/event-streams/sdks/rudderstack-javascript-sdk/supported-api/#consent-api" ><code>consent</code> API</a> once the user consent is available. The SDK then comes out of the pre-consent mode and resumes normal functioning.</p>
<p>A sample implementation for a <a href="https://www.rudderstack.com/docs/data-governance/consent-management/custom-consent-manager/javascript/" >custom provider</a> is shown below:</p>
<div class="rs-code">
  <div class="rs-code__head">html<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-html" data-lang="html">&lt;script type = &#34;text/javascript&#34;&gt;
  // consent provider callback
  function ConsentManagerWrapper() { /// Pseudo name
    if (window.isConsented()) { // Pseudo name

      // Pass the allowed and denied category IDs for custom setup
      rudderanalytics.consent({
        options: {
          trackConsent: true / false, // Optional; default is false
          consentManagement: {
            allowedConsentIds: [&#39;&lt;category_id_1&gt;&#39;,&#39;&lt;category_id_2&gt;&#39;,.....], // Required for Custom provider
            deniedConsentIds: [&#39;&lt;category_id_3&gt;&#39;,&#39;&lt;category_id_4&gt;&#39;,.....]
          }, // Required for Custom provider
          storage: {
            type: &#34;cookieStorage&#34;, // Other supported values are &#34;localStorage&#34;,&#34;sessionStorage&#34;, &#34;memoryStorage&#34;, and &#34;none&#34;
            entries: {
              userId: {
                type: &#34;localStorage&#34; // Other supported values are &#34;cookieStorage&#34;,&#34;sessionStorage&#34;, &#34;memoryStorage&#34;, and &#34;none&#34;
              },
              userTraits: {
                type: &#34;cookieStorage&#34; // Other supported values are &#34;localStorage&#34;,&#34;sessionStorage&#34;, &#34;memoryStorage&#34;, and &#34;none&#34;
              },
              sessionInfo: {
                type: &#34;cookieStorage&#34; // Other supported values are &#34;localStorage&#34;,&#34;sessionStorage&#34;, &#34;memoryStorage&#34;, and &#34;none&#34;
              }
            }
          }, // Optional
          integrations: IntegrationOpts, // Optional
          discardPreConsentEvents: true / false, // Optional; default is false
          sendPageEvent: true / false // Optional, default is false
        }
      });
    }
  } 
&lt;/script&gt;</code></pre></div>
</div>
<p>The <code>consent</code> API options are listed below:</p>
<table>
  <thead>
      <tr>
          <th>Parameter</th>
          <th>Type</th>
          <th>Description</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>trackConsent</code></td>
          <td>Boolean</td>
          <td>Determines if the SDK should send a <code>track</code> event with the name <code>Consent Management Interaction</code>. <br /><br /><strong>Default value</strong>: <code>false</code></td>
      </tr>
      <tr>
          <td><code>consentManagement</code></td>
          <td>Object</td>
          <td>Lets you pass the user consent data in case of a <a href="https://www.rudderstack.com/docs/data-governance/consent-management/custom-consent-manager/" >custom consent management provider</a>. The SDK <strong>requires</strong> the <code>allowedConsentIds</code> and <code>deniedConsentIds</code> fields in case of a <strong>Custom</strong> consent provider.</td>
      </tr>
      <tr>
          <td><code>storage</code></td>
          <td>Object</td>
          <td>Lets you configure the different storage-specific options like: <br /><br /><ul><li><a href="https://www.rudderstack.com/docs/sources/event-streams/sdks/rudderstack-javascript-sdk/data-storage-cookies/persistent-data-storage/#set-storage-type" ><code>storage.type</code></a>: Specify where the persisted data should be stored.</li><li><a href="https://www.rudderstack.com/docs/sources/event-streams/sdks/rudderstack-javascript-sdk/data-storage-cookies/persistent-data-storage/##set-storage-for-specific-information-type" ><code>storage.entries</code></a>: Lets you define storage for specific type of persisted user data.</li></ul></td>
      </tr>
      <tr>
          <td><code>integrations</code></td>
          <td>Object</td>
          <td>Instructs the SDK to filter the integrations before the consent filtering takes effect.</td>
      </tr>
      <tr>
          <td><code>discardPreConsentEvents</code></td>
          <td>Boolean</td>
          <td>Determines if the SDK should discard all the pre-consent events buffered previously. <br /><br /><strong>Default value</strong>: <code>false</code></td>
      </tr>
      <tr>
          <td><code>sendPageEvent</code></td>
          <td>Boolean</td>
          <td>Determines if the SDK should send a <code>page</code> event. <br /><br /><strong>Default value</strong>: <code>false</code></td>
      </tr>
  </tbody>
</table>
<p>The SDK does the following once you invoke the <code>consent</code> API:</p>
<ul>
<li>Loads the device mode integrations based on consent.</li>
<li>Fetches the consent information from the consent manager.</li>
<li>Stores persistent user information like <code>userId</code>, <code>anonymousId</code>, <code>traits</code>, etc. according to the specified <a href="https://www.rudderstack.com/docs/sources/event-streams/sdks/rudderstack-javascript-sdk/data-storage-cookies/persistent-data-storage/#set-storage-type" ><code>storage</code></a> option.</li>
<li>Discards or replays the buffered pre-consent events to the destinations based on the <code>discardPreconsentEvents</code> parameter.</li>
</ul>
<p>The SDK also sends any events received after the user gives consent to the destinations immediately.</p>

<p>See <a href="https://www.rudderstack.com/docs/sources/event-streams/sdks/rudderstack-javascript-sdk/consent-management/" >Consent Management in JavaScript SDK</a> for more information.</p>
<!-- end-chunk -->
<!-- begin-chunk -->
<h2 id="query-string-api">Query string API</h2><p>RudderStack&rsquo;s <strong>Query string API</strong> lets you trigger the <code>track</code>, <code>identify</code>, and <code>setAnonymousId</code> calls using query parameters within the URL.</p>
<p>You can use this API to achieve the following use cases:</p>
<ul>
<li>Track actions that redirect users to a new web page.</li>
<li>Implement consistent identity tracking for users (known and anonymous) across multiple top-level domains.</li>
</ul>

<html lang="en">
<blockquote class="info">
  <div class="tip-quote">
    
    <div class="tip-text">The JavaScript SDK executes these calls immediately upon loading, making them the first set of events processed by the SDK even if there are any buffered calls on the web page.</div>
  </div>
</blockquote>

</html>
<table>
  <thead>
      <tr>
          <th>Parameter</th>
          <th>Action</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>ajs_aid</code></td>
          <td>Triggers a <code>rudderanalytics.setAnonymousId()</code> call with <code>anonymousId</code> set to the parameter value.</td>
      </tr>
      <tr>
          <td><code>ajs_uid</code></td>
          <td>Triggers a <code>rudderanalytics.identify()</code> call with <code>userId</code> set to the parameter value.</td>
      </tr>
      <tr>
          <td><code>ajs_trait_&lt;trait&gt;</code></td>
          <td>Triggers a <code>rudderanalytics.identify()</code> call even if only traits are provided. Essentially, it will set/update the traits of an existing or anonymous user. <br /><br /><code>rudderanalytics.identify(&lt;traits&gt;)</code></td>
      </tr>
      <tr>
          <td><code>ajs_event</code></td>
          <td>Triggers a <code>rudderanalytics.track()</code> call with the event name set to the parameter value.</td>
      </tr>
      <tr>
          <td><code>ajs_prop_&lt;property&gt;</code></td>
          <td>Populates the <code>properties</code> object of the <code>track</code> call. <br /><br />
<html lang="en">
<blockquote class="info">
  <div class="tip-quote">
    
    <div class="tip-text">This parameter requires <code>ajs_event</code> to be present in the query string.</div>
  </div>
</blockquote>

</html></td>
      </tr>
  </tbody>
</table>
<p>For example, consider the following URL containing the query string parameters:</p>
<p><code>https://example.com/?ajs_uid=12345&amp;ajs_event=test%20event&amp;ajs_aid=abcde&amp;ajs_prop_testProp=prop1&amp;ajs_trait_name=Firstname+Lastname</code></p>
<p>It triggers the following API calls (in order):</p>
<div class="rs-code">
  <div class="rs-code__head">javascript<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript">// Sets the anonymous ID
rudderanalytics.setAnonymousId(&#34;abcde&#34;);

// Identify call
rudderanalytics.identify(&#34;12345&#34;, {
  name: &#34;Firstname Lastname&#34;
});

// Track call
rudderanalytics.track(&#34;test event&#34;, {
  testProp: &#34;prop1&#34;
});</code></pre></div>
</div>
<p>You can also trigger an <code>identify</code> call with only traits by providing <code>ajs_trait_*</code> parameters without <code>ajs_uid</code>:</p>
<p><code>https://example.com/?ajs_trait_email=user@example.com&amp;ajs_trait_name=Name</code></p>
<p>This triggers the following API call:</p>
<div class="rs-code">
  <div class="rs-code__head">javascript<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript">rudderanalytics.identify({
  email: &#34;user@example.com&#34;,
  name: &#34;Name&#34;
});</code></pre></div>
</div>
<!-- end-chunk -->
<!-- begin-chunk -->
<h2 id="context-and-traits">Context and traits</h2><p>This section describes the <code>context</code> and <code>traits</code> objects in the JavaScript SDK in detail.</p>
<!-- end-chunk -->
<!-- begin-chunk -->
<h4 id="context">Context</h4><p>The <code>context</code> object in the event payload is a dictionary of additional information about a particular event. It contains:</p>
<ul>
<li>Event or user-specific data provided through the API as <code>apiOptions</code></li>
<li>Data automatically captured by the JavaScript SDK.</li>
</ul>
<p>See <a href="https://www.rudderstack.com/docs/event-spec/standard-events/common-fields/#automatically-collected-contextual-fields" >Contextual fields</a> for the complete list of auto-captured data.</p>

<html lang="en">
<blockquote class="info">
  <div class="tip-quote">
    
    <div class="tip-text">The SDK merges the <code>apiOptions</code> data with these auto-captured contextual fields and makes them available in the event payload.</div>
  </div>
</blockquote>

</html>
<!-- end-chunk -->
<!-- begin-chunk -->
<h4 id="traits">Traits</h4><p>The <code>traits</code> object is an optional dictionary included within <a href="#context" ><code>context</code></a> specifying the user&rsquo;s unique traits. This is a very useful field for linking the user&rsquo;s information from a previously made <a href="#identify" ><code>identify</code></a> call to the subsequent calls, for example, <a href="#track" ><code>track</code></a> or <a href="#page" ><code>page</code></a>.</p>
<!-- end-chunk -->
<!-- begin-chunk -->
<h4 id="use-case-1">Use case</h4><p>See the following <code>identify</code> event:</p>
<div class="rs-code">
  <div class="rs-code__head">javascript<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript">rudderanalytics.identify(&#34;1hKOmRA4el9Zt1WSfVJIVo4GRlm&#34;, {
  name: &#34;Alex Keener&#34;,
  email: &#34;alex@example.com&#34;,
  subscriptionStatus: &#34;subscribed&#34;,
  plan: &#34;Silver&#34;
});</code></pre></div>
</div>
<p>The traits in the above event are <code>name</code>, <code>email</code>, <code>subscriptionStatus</code>, and <code>plan</code>. To add or override any traits in the subsequent <code>track</code> or <code>page</code> events triggered by the user, passing them in the <code>traits</code> object as <a href="#apioptions" ><code>apiOptions</code></a> as shown:</p>
<div class="rs-code">
  <div class="rs-code__head">javascript<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript">rudderanalytics.track(
  &#34;Subscription Update&#34;, {
    campaign: &#34;Subscribe&#34;
  }, {
    traits: {
      plan: &#34;Gold&#34;,
      addOn: true
    }
  }
);</code></pre></div>
</div>
<p>The above snippet will add a new trait <code>addOn</code> and update the user trait <code>plan</code> to <code>Gold</code> for the <code>track</code> event. However, note that the subsequent events will still have the old traits.</p>
<!-- end-chunk -->
<!-- begin-chunk -->
<h2 id="disable-trait-forwarding">Disable trait forwarding</h2><p>By default, the JavaScript SDK automatically forwards the user traits from <code>identify</code> calls to the subsequent calls. You can override this behavior for <strong>each</strong> call through the <code>apiOptions</code> argument by setting <code>traits</code> to <code>null</code>.</p>
<p>A sample <code>track</code> call highlighting this functionality is shown:</p>
<div class="rs-code">
  <div class="rs-code__head">javascript<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript">rudderanalytics.track(
  &#34;Order Completed&#34;, {
    revenue: 30,
    currency: &#34;USD&#34;,
    user_actual_id: 12345
  }, {
    traits: null
  }
  () =&gt; {
    console.log(&#34;Track event successfully submitted to the RudderStack SDK.&#34;);
  }
);</code></pre></div>
</div>
<p>The above snippet removes the <code>context.traits</code> object only for the specific <code>Order Completed</code> event.</p>
<p>Note that:</p>
<ul>
<li>You can use this functionality for <code>track</code>, <code>page</code>, and <code>alias</code> calls.</li>
<li>The persisted user traits are not impacted at all.</li>
<li>You can also override a subset of user traits using the same approach.</li>
</ul>
<!-- end-chunk -->
<!-- begin-chunk -->
<h2 id="register-custom-integrations">Register custom integrations</h2><p>The JavaScript SDK provides a <code>addCustomIntegration</code> API to register your <a href="https://www.rudderstack.com/docs/destinations/custom-web-device-mode-integrations/" >custom web device mode integration</a> with the SDK.</p>
<p>See the following guides for more information:</p>
<ul>
<li><a href="https://www.rudderstack.com/docs/sources/event-streams/sdks/rudderstack-javascript-sdk/register-custom-integrations/" ><code>addCustomIntegration</code> API Reference</a></li>
<li><a href="https://www.rudderstack.com/docs/destinations/custom-web-device-mode-integrations/setup/" >How to Create Custom Web Device Mode Integrations</a></li>
</ul>

