EventsSending Events

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/events

Authentication

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

StatusMeaning
200 OKEvent accepted
400 Bad RequestInvalid event format (malformed JSON, missing required fields)
401 UnauthorizedInvalid or missing write key
403 ForbiddenEvent type not allowed for this write key
422 Unprocessable EntityEvent rejected by contract validation
429 Too Many RequestsRate limit exceeded

Common Fields

All event types share these fields:

FieldTypeRequiredDescription
typestringYesEvent type: track, identify, page, screen, group
userIdstringConditionalThe known user identifier. Required if anonymousId is not provided.
anonymousIdstringConditionalA client-generated anonymous identifier. Required if userId is not provided.
timestampstring (ISO 8601)NoWhen the event occurred. Defaults to server receipt time.
contextobjectNoAdditional context (IP, user agent, locale, device info, etc.)
integrationsobjectNoPer-destination forwarding overrides (e.g., { "Amplitude": false })
messageIdstringNoClient-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

EventPropertiesDescription
Signed Upplan, sourceUser created an account
Logged InmethodUser signed in
Product Viewedproduct_id, name, category, priceUser viewed a product page
Product Addedproduct_id, name, price, quantity, cart_idUser added item to cart
Cart Viewedcart_id, products[], totalUser viewed their cart
Checkout Startedorder_id, total, products[]User initiated checkout
Order Completedorder_id, total, currency, products[], couponUser completed a purchase
Subscription Createdplan, price, intervalUser 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 anonymousId is provided, the traits are associated with the anonymous profile until an identify call with both anonymousId and userId links 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:

FieldTypeDescription
context.ipstringUser’s IP address (used for geo enrichment)
context.userAgentstringBrowser/device user agent string
context.localestringUser’s locale (e.g., en-US)
context.timezonestringUser’s timezone (e.g., America/New_York)
context.page.urlstringCurrent page URL
context.page.pathstringCurrent page path
context.page.referrerstringReferring URL
context.page.titlestringPage title
context.device.typestringDevice type (ios, android, web)
context.device.modelstringDevice model
context.device.manufacturerstringDevice manufacturer
context.os.namestringOperating system name
context.os.versionstringOperating system version
context.app.namestringApplication name
context.app.versionstringApplication version
context.campaign.sourcestringUTM source
context.campaign.mediumstringUTM medium
context.campaign.namestringUTM 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