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)
- Open your Terminal.
- Use the
echocommand combined withbase64to encode your API Key. Ensure you add a colon (:) after your API Key before encoding it since the format should beusername:passwordand 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:
- 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();
});
- 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();
});
- 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:
| Scenario | Example | Solution |
|---|---|---|
| Cross-subdomain | www.example.com → app.example.com | Set cookies at TLD (.example.com) |
| Cross-TLD | example.com → example.io | Pass 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:
- NodeJS SDK: Documented in our GitHub repository.
- Go SDK: Also available on GitHub.
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