Skip to main content

Server Side Tracking

Disclaimer

Server-side tracking is an advanced feature that differs significantly from client-side tracking commonly implemented through platforms like Google Tag Manager (GTM). While GTM allows for relatively straightforward analytics setup by marketing professionals or non-technical users, server-side tracking requires a deeper technical understanding and direct implementation within your server's codebase.

Server-side tracking provides a robust method for capturing events directly from your backend systems, offering enhanced data privacy and bypassing limitations of client-side tracking. This guide outlines the process for setting up server-side tracking with Dreamdata.

Before proceeding, ensure you have the following:

  • Access to your server/backend environment.
  • Dreamdata Source API Key: This is required for authenticating with the Tracking API. You can locate your API Key in the Dreamdata platform under Data Platform > Sources > Server Side Analytics APIs.

Key Differences:

  • Implementation Complexity: Server-side tracking cannot be set up through GTM and requires a developer for implementation.
  • Data Control: It offers more control over the data being sent, improving privacy and data security.
  • Technical Knowledge: Understanding of backend development and server architecture is necessary. Server-side tracking is recommended for teams seeking advanced analytics capabilities and those with access to technical resources for implementation.

Authentication to the Tracking API

To authenticate with the Dreamdata Tracking API, you'll use HTTP Basic Auth. This process requires encoding your Dreamdata source API Key in base64, formatted as username:password — with your API key as the username and leaving the password field empty.

For example, if your API key is abc123, you authenticate like this:

curl -u "abc123:" -X POST https://api.dreamdata.cloud/v1/batch \
-H 'Content-Type: application/json' \
-d ...

Encoding Your API Key in Base64 (Unix-based Systems)

  1. Open your Terminal.
  2. Use the echo command combined with base64 to encode your API Key. Ensure you add a colon (:) after your API Key before encoding it since the format should be username:password and the password is empty.
echo -n 'your_api_key_here:' | base64

Replace your_api_key_here with your actual Dreamdata source API Key.

This command will output a base64-encoded string that represents your API Key followed by a colon. You'll use this encoded string in your authentication header when making API requests.

Example

If your API Key is abc123, you would run:

echo -n 'abc123:' | base64

The output will be something like YWJjMTIzOg==, which you'll use in your authentication header:

curl -u "YWJjMTIzOg==" -X POST https://api.dreamdata.cloud/v1/batch \
-H 'Content-Type: application/json' \
-d ...

Note: The -n flag in the echo command prevents a newline character from being added at the end of the string, ensuring the encoding is accurate.

Sending Data: Track & Identify Events

Dreamdata's endpoint supports sending batches of data, limited to 500kb per request. These batches can include a mix of identify and track events. Here's how to format such a request:

{
"messageId": "6f47f5a0-4118-42de-9e15-95cf9ed2a426",
"sentAt": "2015-12-02T00:30:08.276Z",
"batch": [
{
"type": "identify",
"messageId": "6ad2be86-6d78-43bd-8a5b-846ddbc042c2",
"userId": "019mr8mf4r",
"traits": {
"email": "jake@yahoo.com",
"name": "Jake Peterson",
"age": 26
},
"context": {
"ip": "24.5.68.47",
"library": {
"name": "customer",
"version": "v1"
},
"campaign": {
"name": "my_campaign",
"source": "demo",
"medium": "calendly",
"term": "",
"content": ""
}
},
"timestamp": "2012-12-02T00:30:08.276Z"
},
{
"type": "track",
"messageId": "3f8236bc-c010-43bb-a341-cd30b5228e9d",
"userId": "019mr8mf4r",
"event": "Song Played",
"properties": {
"name": "Fallin for You",
"artist": "Dierks Bentley"
},
"context": {
"ip": "24.5.68.47",
"page": {
"referrer": "http://localhost:3000/test",
"url": "http://localhost:3000/test/path?param=a088fb06-a208-4552-b4b7-28fb7f95aeaf"
},
"userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36",
"campaign": {
"name": "my_campaign",
"source": "demo",
"medium": "calendly",
"term": "",
"content": ""
}
},
"timestamp": "2012-12-02T00:30:12.984Z"
}
]
}

Replace placeholders with actual data relevant to your tracking needs. Each event needs a unique messageId, and timestamps should be in ISO 8601 format.

User Identification

When implementing server-side tracking, you need to decide how to identify users. The SDK requires either a userId or anonymousId for each event.

When to Use userId

Use userId when you have an authenticated or known user:

  • User is logged in to your application
  • You have a CRM or database ID for the user
  • The identifier comes from your authentication system
{
"type": "track",
"userId": "user-123",
"event": "Order Completed"
}

When to Use anonymousId

Use anonymousId when tracking anonymous visitors:

  • User is not logged in
  • You want to track activity before authentication
  • You need to link pre-login and post-login behavior

Generating anonymousId server-side:

For purely server-side integrations, you need to generate and persist the anonymousId yourself. Common strategies:

  1. Session-based: Store a UUID in the user's session
// Express.js example
app.use((req, res, next) => {
if (!req.session.anonymousId) {
req.session.anonymousId = crypto.randomUUID();
}
next();
});
  1. Cookie-based: Set a cookie with a UUID on first visit
app.use((req, res, next) => {
if (!req.cookies.dd_anonymous_id) {
const anonId = crypto.randomUUID();
res.cookie("dd_anonymous_id", anonId, {
maxAge: 365 * 24 * 60 * 60 * 1000,
});
req.anonymousId = anonId;
} else {
req.anonymousId = req.cookies.dd_anonymous_id;
}
next();
});
  1. Cookieless (company-level only): Use a static placeholder when you only need company-level attribution via IP lookup
{
"type": "track",
"anonymousId": "cookieless",
"event": "Page Viewed",
"context": { "ip": "203.0.113.42" }
}

See Server-Side Cookieless Tracking for details.

Linking Anonymous and Known Users

When a user logs in, use alias to connect their anonymousId to their userId:

{
"type": "alias",
"userId": "user-123",
"previousId": "anon-xyz-789"
}

Cross-Domain Tracking

When your application spans multiple domains, you need to ensure the anonymousId persists to maintain a unified user journey:

ScenarioExampleSolution
Cross-subdomainwww.example.comapp.example.comSet cookies at TLD (.example.com)
Cross-TLDexample.comexample.ioPass ID via URL parameter or shared backend

Cross-subdomain: Set the cookie domain to the top-level domain with a leading dot:

res.cookie("dd_anonymous_id", anonId, {
domain: ".example.com", // Shared across all subdomains
path: "/",
maxAge: 365 * 24 * 60 * 60 * 1000,
sameSite: "lax",
secure: true,
});

Cross-TLD: Since cookies can't be shared across different TLDs, pass the anonymousId via URL parameter when linking between domains:

// Redirect with anonymousId
const url = new URL("https://example.io/landing");
url.searchParams.set("dd_anon_id", req.anonymousId);
res.redirect(url.toString());

For complete implementation details and code examples, see the Node.js SDK Cross-Domain Tracking documentation.

Endpoint for Sending Events

To submit your events to Dreamdata, make a POST request with your batch payload to:

curl -u "your-api-key:" -X POST https://api.dreamdata.cloud/v1/batch \
-H 'Content-Type: application/json' \
-d @path-to-your-json-file

Replace your-api-key with your actual Dreamdata API key and path-to-your-json-file with the file path of your JSON payload.

SDK Support

Dreamdata provides SDKs for easier integration within your application:

Example CURL Request

To send your events using curl, assuming your JSON payload is saved in example.json:

curl -u "your-api-key:" -X POST https://api.dreamdata.cloud/v1/batch \
-H 'Content-Type: application/json' \
-d @example.json