Setting Up Event Forwarding
This guide walks you through collecting real-time events from your applications and forwarding them to analytics and marketing tools. By the end, you’ll have instrumented your app, defined event contracts for data quality, configured forwarding rules, set up consent management, and monitored everything in the event debugger.
When to Use Event Forwarding
Event forwarding is the right approach when you need to:
- Send real-time behavioral data (page views, clicks, purchases) to analytics tools like Amplitude or Mixpanel
- Feed marketing automation platforms with event triggers (e.g., “user completed checkout” triggers a thank-you email)
- Collect events from multiple sources (web, mobile, server) into a single pipeline
- Enforce data quality on incoming events with schema validation
- Manage user consent for event data processing
- Write events to your warehouse for historical analysis alongside your batch data
Prerequisites
- A SignalSmith workspace with at least one connected source
- An application (web, mobile, or server-side) that you want to instrument
- A destination account (e.g., Amplitude, Mixpanel, Google Analytics) for receiving forwarded events
- Admin or Editor role in your SignalSmith workspace
Step 1: Create Write Keys
Write keys authenticate event sources when sending data to the SignalSmith events API. Create a separate write key for each event source so you can track where events originate and revoke access independently.
- Navigate to Events > Write Keys in the left sidebar
- Click Create Write Key
- Name it descriptively to identify the source:
Production Web App— For your main websiteiOS App— For your iOS applicationBackend Server— For server-side eventsStaging Environment— For development and testing
- Click Create
- Copy the generated key immediately — It will only be shown once. Store it securely in your application’s environment variables.
Repeat for each event source. Having separate keys per source lets you:
- Track origin — See which source generated each event in the debugger
- Revoke independently — Disable one source without affecting others
- Monitor volume — Track event volume per source for capacity planning
Step 2: Instrument Your Application
SignalSmith’s event API is Segment-compatible, supporting track, identify, page, and group event types. Integrate with your application using direct HTTP calls.
JavaScript (Browser)
// signalsmith-events.js — Lightweight event tracking client
const SIGNALSMITH_ENDPOINT = 'https://your-instance.signalsmith.io/api/v1/events';
const WRITE_KEY = process.env.SIGNALSMITH_WRITE_KEY;
async function track(eventName, properties = {}) {
await fetch(`${SIGNALSMITH_ENDPOINT}/track`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${WRITE_KEY}`
},
body: JSON.stringify({
type: 'track',
event: eventName,
userId: getCurrentUserId(),
anonymousId: getAnonymousId(),
properties,
timestamp: new Date().toISOString(),
context: {
page: { url: window.location.href, title: document.title },
userAgent: navigator.userAgent
}
})
});
}
async function identify(userId, traits = {}) {
await fetch(`${SIGNALSMITH_ENDPOINT}/identify`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${WRITE_KEY}`
},
body: JSON.stringify({
type: 'identify',
userId,
traits,
timestamp: new Date().toISOString()
})
});
}
async function page(name, properties = {}) {
await fetch(`${SIGNALSMITH_ENDPOINT}/page`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${WRITE_KEY}`
},
body: JSON.stringify({
type: 'page',
name,
userId: getCurrentUserId(),
properties,
timestamp: new Date().toISOString()
})
});
}
// Usage examples
track('Product Viewed', {
product_id: 'prod_123',
product_name: 'Premium Widget',
price: 49.99,
category: 'Widgets'
});
identify('user_456', {
email: 'jane@example.com',
plan: 'enterprise',
company: 'Acme Corp'
});
page('Pricing Page', {
referrer: document.referrer
});Server-Side (curl)
# Track event
curl -X POST https://your-instance.signalsmith.io/api/v1/events/track \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_WRITE_KEY" \
-d '{
"type": "track",
"event": "Order Completed",
"userId": "user_456",
"properties": {
"order_id": "ord_789",
"total": 149.99,
"currency": "USD",
"items": 3,
"coupon_code": "SUMMER20"
},
"timestamp": "2024-12-15T14:30:00Z"
}'
# Identify user
curl -X POST https://your-instance.signalsmith.io/api/v1/events/identify \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_WRITE_KEY" \
-d '{
"type": "identify",
"userId": "user_456",
"traits": {
"email": "jane@example.com",
"name": "Jane Doe",
"plan": "enterprise",
"created_at": "2024-01-15T10:00:00Z"
}
}'Best Practices for Instrumentation
- Always include
userIdfor authenticated users — This enables identity stitching and profile enrichment - Use
anonymousIdfor unauthenticated users — Generate a stable anonymous ID (e.g., UUID stored in a cookie) so pre-login events can be linked post-login - Include timestamps — Always pass an ISO 8601 timestamp. If omitted, the server uses receipt time, which may not reflect when the event actually occurred.
- Keep properties flat — Avoid deeply nested objects. Flat properties are easier to query in your warehouse and map to destination schemas.
- Use consistent naming — Adopt a naming convention (e.g., “Object Action” like “Product Viewed”, “Order Completed”) and apply it across all sources.
Step 3: Define Event Contracts
Event contracts enforce data quality by validating incoming events against a schema. Contracts define which properties are required, their expected data types, and what happens when an event violates the contract.
- Navigate to Events > Contracts
- Click Create Contract
- Select the event name (e.g., “Order Completed”)
- Define the schema:
| Property | Type | Required | Description |
|---|---|---|---|
order_id | string | Yes | Unique order identifier |
total | number | Yes | Order total in base currency |
currency | string | Yes | ISO 4217 currency code |
items | integer | No | Number of items in the order |
coupon_code | string | No | Applied coupon code |
-
Set the violation policy:
- Allow — Accept the event even if it violates the contract (log the violation for review)
- Drop Property — Accept the event but strip non-conforming properties
- Reject — Reject the entire event and return a 422 error to the sender
-
Click Save
Contract Strategy
Start with Allow mode for new events to collect data on what’s being sent without blocking anything. Once you understand the event shape, tighten to Drop Property or Reject to enforce quality.
Create contracts for your most critical events first:
| Priority | Events | Why |
|---|---|---|
| High | Order Completed, Signup Completed, Subscription Started | Revenue-impacting — bad data here means wrong analytics |
| Medium | Product Viewed, Cart Updated, Search Performed | Behavioral analytics — important but less critical |
| Lower | Page Viewed, Button Clicked | High volume, lower individual impact |
Step 4: Configure Forwarding Rules
Forwarding rules route events from SignalSmith to downstream analytics and marketing tools in real time.
-
Navigate to Events > Forwarding
-
Click Create Forwarding Rule
-
Select a destination (e.g., Amplitude)
-
Configure which events to forward:
- All events — Forward everything (simple but may be costly for high-volume sources)
- Specific events — Select event names to forward (e.g., only “Order Completed” and “Signup Completed”)
- Filter by properties — Forward events matching specific property conditions (e.g., only events where
total > 100)
-
Configure property mapping if the destination uses different field names:
| SignalSmith Property | Destination Property | Notes |
|---|---|---|
userId | user_id | Amplitude uses snake_case |
properties.total | revenue | Map to Amplitude’s revenue field |
properties.product_id | item_id | Rename for destination schema |
- Click Save
Forwarding to Multiple Destinations
You can create multiple forwarding rules for the same events. For example:
- Forward all events to your data warehouse for analysis
- Forward revenue events to Amplitude for product analytics
- Forward marketing events to Braze for campaign triggering
- Forward page views to Google Analytics for web analytics
Each forwarding rule operates independently, so events can flow to multiple destinations simultaneously.
Step 5: Set Up Consent Management
Consent management ensures that events are only forwarded to destinations when the user has granted the appropriate consent.
- Navigate to Events > Consent
- Define consent categories that match your privacy policy:
| Category | Description | Destinations |
|---|---|---|
analytics | Product analytics and usage tracking | Amplitude, Mixpanel |
marketing | Marketing automation and email campaigns | Braze, HubSpot |
advertising | Ad targeting and retargeting | Google Ads, Facebook Ads |
functional | Essential product functionality | Internal systems |
- Map each forwarding rule to a consent category
- Set the default consent state for new users (
grantedordenieddepending on your jurisdiction)
Sending Consent Events
When a user grants or revokes consent, send a consent event:
// User grants marketing consent
track('Consent Updated', {
category: 'marketing',
status: 'granted',
source: 'cookie_banner'
});
// User revokes advertising consent
track('Consent Updated', {
category: 'advertising',
status: 'denied',
source: 'privacy_settings'
});SignalSmith automatically updates the user’s consent state and begins or stops forwarding events to the affected destinations.
Step 6: Monitor in the Event Debugger
The event debugger provides a real-time view of events flowing through your pipeline.
- Navigate to Events > Live
- See events arriving in real-time as a scrolling feed
- Use filters to focus on specific events:
- Event name — Show only “Order Completed” events
- User ID — Show all events for a specific user (useful for debugging)
- Write key — Show events from a specific source
- Contract status — Show only events that violated a contract
- Click any event to expand its full payload — properties, context, contract validation result, and forwarding status
- Check forwarding delivery status:
- Delivered — Event was successfully forwarded to the destination
- Pending — Event is queued for forwarding
- Failed — Forwarding failed (click for error details)
- Blocked — Event was blocked by consent or forwarding rules
Debugging Common Issues
| Issue | How to Debug |
|---|---|
| Events not appearing | Check the write key is correct. Filter by write key to isolate. |
| Contract violations | Filter by contract status “violated.” Review the violation details. |
| Forwarding failures | Click the failed delivery to see the destination’s error response. |
| Missing properties | Expand the event to see what was actually sent vs. what the contract expects. |
| Duplicate events | Check timestamps — your app may be sending the same event twice. |
Step 7: Write Events to Your Warehouse
Persist events in your data warehouse for historical analysis, joining with your batch data.
- Navigate to Events > Warehouse
- Click Configure Warehouse Destination
- Select your warehouse source (the same warehouse connected as a source)
- Configure the target schema and table name (e.g.,
SIGNALSMITH_EVENTS.RAW_EVENTS) - Set the write frequency:
- Real-time — Events are written as they arrive (highest cost, lowest latency)
- Micro-batch — Events are buffered and written every 1-5 minutes (good balance)
- Batch — Events are written on a schedule (e.g., every hour, lowest cost)
- Click Save
Once configured, events are available in your warehouse for SQL analysis:
SELECT
event,
COUNT(*) AS event_count,
COUNT(DISTINCT user_id) AS unique_users
FROM SIGNALSMITH_EVENTS.RAW_EVENTS
WHERE timestamp >= DATEADD(day, -7, CURRENT_TIMESTAMP)
GROUP BY event
ORDER BY event_count DESCVerification
After completing all steps, verify your setup:
- Send a test event from your application
- Check the debugger — The event should appear in the live feed within seconds
- Verify contract validation — If you defined a contract, check that it passes
- Check forwarding — Confirm the event arrived at your destination (check Amplitude, Mixpanel, etc.)
- Check consent — Send an event for a user who hasn’t granted consent and verify it’s blocked from forwarding
- Query the warehouse — After the configured write delay, verify the event is in your warehouse table
Next Steps
- Events documentation — Full reference for event types, API, and configuration
- Event Contracts — Advanced contract configuration
- Consent Management — Detailed consent workflows
- Journey Automation — Use events as journey triggers
- Glossary — Definitions of event-related terms