Sending Events
SignalSmith’s Events API is compatible with the Segment specification, making it easy to migrate from Segment or use existing Segment libraries. This page covers the API format for all event types with full examples.
API Endpoint
POST https://your-workspace.signalsmith.dev/api/v1/eventsAuthentication
Events are authenticated using a write key sent as HTTP Basic auth (write key as username, empty password):
curl -X POST https://your-workspace.signalsmith.dev/api/v1/events \
-H "Authorization: Basic $(echo -n 'YOUR_WRITE_KEY:' | base64)" \
-H "Content-Type: application/json" \
-d '{ ... }'Response
| Status | Meaning |
|---|---|
200 OK | Event accepted |
400 Bad Request | Invalid event format (malformed JSON, missing required fields) |
401 Unauthorized | Invalid or missing write key |
403 Forbidden | Event type not allowed for this write key |
422 Unprocessable Entity | Event rejected by contract validation |
429 Too Many Requests | Rate limit exceeded |
Common Fields
All event types share these fields:
| Field | Type | Required | Description |
|---|---|---|---|
type | string | Yes | Event type: track, identify, page, screen, group |
userId | string | Conditional | The known user identifier. Required if anonymousId is not provided. |
anonymousId | string | Conditional | A client-generated anonymous identifier. Required if userId is not provided. |
timestamp | string (ISO 8601) | No | When the event occurred. Defaults to server receipt time. |
context | object | No | Additional context (IP, user agent, locale, device info, etc.) |
integrations | object | No | Per-destination forwarding overrides (e.g., { "Amplitude": false }) |
messageId | string | No | Client-generated unique ID for deduplication. Auto-generated if omitted. |
Track Events
Track events record user actions — anything a user does that you want to measure.
Format
{
"type": "track",
"userId": "user_123",
"event": "Order Completed",
"properties": {
"order_id": "ord_456",
"total": 99.99,
"currency": "USD",
"products": [
{
"product_id": "prod_789",
"name": "SignalSmith T-Shirt",
"price": 29.99,
"quantity": 2
},
{
"product_id": "prod_012",
"name": "SignalSmith Sticker Pack",
"price": 9.99,
"quantity": 4
}
],
"coupon": "SUMMER20",
"payment_method": "credit_card"
},
"timestamp": "2025-03-15T14:30:00Z",
"context": {
"ip": "203.0.113.42",
"userAgent": "Mozilla/5.0 ...",
"locale": "en-US",
"page": {
"url": "https://shop.example.com/checkout/confirmation",
"referrer": "https://shop.example.com/checkout/payment"
}
}
}curl Example
curl -X POST https://your-workspace.signalsmith.dev/api/v1/events \
-H "Authorization: Basic $(echo -n 'sk_live_abc123:' | base64)" \
-H "Content-Type: application/json" \
-d '{
"type": "track",
"userId": "user_123",
"event": "Order Completed",
"properties": {
"order_id": "ord_456",
"total": 99.99,
"currency": "USD",
"products": [
{ "product_id": "prod_789", "name": "SignalSmith T-Shirt", "price": 29.99, "quantity": 2 }
]
},
"timestamp": "2025-03-15T14:30:00Z"
}'Common Track Events
| Event | Properties | Description |
|---|---|---|
Signed Up | plan, source | User created an account |
Logged In | method | User signed in |
Product Viewed | product_id, name, category, price | User viewed a product page |
Product Added | product_id, name, price, quantity, cart_id | User added item to cart |
Cart Viewed | cart_id, products[], total | User viewed their cart |
Checkout Started | order_id, total, products[] | User initiated checkout |
Order Completed | order_id, total, currency, products[], coupon | User completed a purchase |
Subscription Created | plan, price, interval | User started a subscription |
Identify Calls
Identify calls associate traits (attributes) with a user. Use them when you learn something new about a user.
Format
{
"type": "identify",
"userId": "user_123",
"traits": {
"email": "jane@example.com",
"name": "Jane Smith",
"plan": "enterprise",
"company": {
"id": "comp_456",
"name": "Acme Corp",
"industry": "Technology",
"employee_count": 250
},
"created_at": "2024-01-15T09:00:00Z",
"lifetime_value": 4500.00,
"newsletter_subscribed": true,
"tags": ["vip", "beta-tester"]
},
"timestamp": "2025-03-15T14:30:00Z",
"context": {
"ip": "203.0.113.42",
"userAgent": "Mozilla/5.0 ..."
}
}curl Example
curl -X POST https://your-workspace.signalsmith.dev/api/v1/events \
-H "Authorization: Basic $(echo -n 'sk_live_abc123:' | base64)" \
-H "Content-Type: application/json" \
-d '{
"type": "identify",
"userId": "user_123",
"traits": {
"email": "jane@example.com",
"name": "Jane Smith",
"plan": "enterprise",
"lifetime_value": 4500.00
}
}'Behavior
- Traits are merged — new traits are added and existing traits are updated
- To remove a trait, set it to
null - Identify calls update the user profile used by audiences and journeys
- If only
anonymousIdis provided, the traits are associated with the anonymous profile until an identify call with bothanonymousIdanduserIdlinks them
Page Views
Page calls record when a user views a page on your website.
Format
{
"type": "page",
"userId": "user_123",
"name": "Pricing",
"category": "Marketing",
"properties": {
"url": "https://www.example.com/pricing",
"path": "/pricing",
"title": "Pricing - Example",
"referrer": "https://www.google.com/",
"search": "?plan=enterprise",
"utm_source": "google",
"utm_medium": "cpc",
"utm_campaign": "brand-q1"
},
"timestamp": "2025-03-15T14:30:00Z"
}curl Example
curl -X POST https://your-workspace.signalsmith.dev/api/v1/events \
-H "Authorization: Basic $(echo -n 'sk_live_abc123:' | base64)" \
-H "Content-Type: application/json" \
-d '{
"type": "page",
"userId": "user_123",
"name": "Pricing",
"properties": {
"url": "https://www.example.com/pricing",
"path": "/pricing",
"title": "Pricing - Example",
"referrer": "https://www.google.com/"
}
}'Screen Views
Screen calls record when a user views a screen in your mobile app. The format is identical to page calls but uses type: "screen".
Format
{
"type": "screen",
"userId": "user_123",
"name": "Settings",
"category": "Account",
"properties": {
"variation": "dark_mode"
},
"timestamp": "2025-03-15T14:30:00Z",
"context": {
"device": {
"type": "ios",
"model": "iPhone 15 Pro",
"manufacturer": "Apple"
},
"os": {
"name": "iOS",
"version": "18.2"
},
"app": {
"name": "MyApp",
"version": "3.1.0",
"build": "245"
}
}
}curl Example
curl -X POST https://your-workspace.signalsmith.dev/api/v1/events \
-H "Authorization: Basic $(echo -n 'sk_live_abc123:' | base64)" \
-H "Content-Type: application/json" \
-d '{
"type": "screen",
"userId": "user_123",
"name": "Settings",
"category": "Account",
"properties": {
"variation": "dark_mode"
},
"context": {
"device": { "type": "ios", "model": "iPhone 15 Pro" }
}
}'Group Calls
Group calls associate a user with a company, organization, or team.
Format
{
"type": "group",
"userId": "user_123",
"groupId": "comp_456",
"traits": {
"name": "Acme Corp",
"industry": "Technology",
"plan": "enterprise",
"employee_count": 250,
"website": "https://acme.example.com",
"created_at": "2023-06-01T00:00:00Z",
"mrr": 15000.00
},
"timestamp": "2025-03-15T14:30:00Z"
}curl Example
curl -X POST https://your-workspace.signalsmith.dev/api/v1/events \
-H "Authorization: Basic $(echo -n 'sk_live_abc123:' | base64)" \
-H "Content-Type: application/json" \
-d '{
"type": "group",
"userId": "user_123",
"groupId": "comp_456",
"traits": {
"name": "Acme Corp",
"industry": "Technology",
"plan": "enterprise",
"employee_count": 250
}
}'Behavior
- Group traits are merged (same as identify)
- A user can belong to multiple groups
- Group associations are used by audience conditions that reference company/account attributes
Batch Endpoint
For server-side integrations sending many events, use the batch endpoint to send up to 500 events in a single request:
curl -X POST https://your-workspace.signalsmith.dev/api/v1/events/batch \
-H "Authorization: Basic $(echo -n 'sk_live_abc123:' | base64)" \
-H "Content-Type: application/json" \
-d '{
"batch": [
{
"type": "track",
"userId": "user_123",
"event": "Product Viewed",
"properties": { "product_id": "prod_789" },
"timestamp": "2025-03-15T14:30:00Z"
},
{
"type": "track",
"userId": "user_456",
"event": "Order Completed",
"properties": { "order_id": "ord_789", "total": 149.99 },
"timestamp": "2025-03-15T14:31:00Z"
}
]
}'Batch Response
The batch endpoint returns a summary:
{
"received": 2,
"accepted": 2,
"rejected": 0,
"errors": []
}If some events are rejected, the errors array contains per-event error details with the event index.
Context Object
The context object provides additional metadata about the event. While optional, it enriches your data for analysis:
| Field | Type | Description |
|---|---|---|
context.ip | string | User’s IP address (used for geo enrichment) |
context.userAgent | string | Browser/device user agent string |
context.locale | string | User’s locale (e.g., en-US) |
context.timezone | string | User’s timezone (e.g., America/New_York) |
context.page.url | string | Current page URL |
context.page.path | string | Current page path |
context.page.referrer | string | Referring URL |
context.page.title | string | Page title |
context.device.type | string | Device type (ios, android, web) |
context.device.model | string | Device model |
context.device.manufacturer | string | Device manufacturer |
context.os.name | string | Operating system name |
context.os.version | string | Operating system version |
context.app.name | string | Application name |
context.app.version | string | Application version |
context.campaign.source | string | UTM source |
context.campaign.medium | string | UTM medium |
context.campaign.name | string | UTM campaign name |
Deduplication
Events are deduplicated using the messageId field. If you send two events with the same messageId, the second is silently ignored. This is useful for retry logic — if your request times out but the server received it, retrying with the same messageId prevents duplicate events.
If you don’t provide a messageId, SignalSmith generates one server-side (no deduplication for those events).
Next Steps
- Event contracts — Enforce schemas on incoming events
- Event transformations — Modify events in-flight
- Event forwarding — Route events to downstream destinations
- Debugging — Verify events are arriving correctly