Skip to main content
The OpenEvent interface represents a single email open event with detailed metadata including device information, geolocation, and duplicate/suppression status.

Fields

id
number
required
Auto-incrementing unique identifier for the open event. This is the primary key.
email_id
string
required
Identifier for the tracked email that was opened. References the email_id from TrackedEmail.
user_id
string
required
Identifier for the user or account that owns this tracking record. Used for data isolation.
recipient
string
required
Email address of the recipient who opened the email.
opened_at
string
required
ISO 8601 timestamp indicating when the email was opened. Format: YYYY-MM-DDTHH:mm:ss.sssZ
ip_address
string | null
IP address from which the email was opened. May be null if the IP address could not be determined. IPv6-mapped IPv4 addresses are normalized to standard IPv4 format.
user_agent
string | null
User agent string from the HTTP request. May be null if not provided. Used for device type detection and duplicate detection.
geo_country
string | null
Country name derived from IP geolocation. May be null if geolocation lookup failed or IP address was not available.
geo_region
string | null
Region or state name derived from IP geolocation. May be null if not available.
geo_city
string | null
City name derived from IP geolocation. May be null if not available.
latitude
number | null
Latitude coordinate from IP geolocation. May be null if not available.
longitude
number | null
Longitude coordinate from IP geolocation. May be null if not available.
device_type
'phone' | 'computer' | 'other'
required
Type of device used to open the email, detected from the user agent string:
  • phone - Mobile devices and tablets
  • computer - Desktop computers and laptops
  • other - Unknown or unrecognized devices
is_duplicate
number
required
Flag indicating whether this open was classified as a duplicate:
  • 0 - Unique open event
  • 1 - Duplicate open (same email opened multiple times from same IP/user agent within a time window)
Duplicate opens are excluded from the open_count metric.
is_sender_suppressed
number
required
Flag indicating whether this open was suppressed by the sender:
  • 0 - Normal open event
  • 1 - Suppressed open (sender called mark-suppress-next before the open occurred)
Suppressed opens are typically from email client prefetching and are excluded from the open_count metric.
suppression_reason
string | null
Reason for suppression if is_sender_suppressed is 1. Currently, the only value is:
  • "mark_suppress_next" - Suppressed via the mark-suppress-next endpoint
  • null - Not suppressed

Returned by

  • GET /dashboard/api/open-events - Returns an array of OpenEvent objects
    • Without query params: Returns all non-duplicate, non-suppressed open events
    • With email_id query param: Returns open events for a specific email

Database schema

Stored in the open_events table with the following SQLite schema:
CREATE TABLE open_events (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  email_id TEXT NOT NULL,
  user_id TEXT NOT NULL,
  recipient TEXT NOT NULL,
  opened_at TEXT NOT NULL DEFAULT (datetime('now')),
  ip_address TEXT,
  user_agent TEXT,
  geo_country TEXT,
  geo_region TEXT,
  geo_city TEXT,
  latitude REAL,
  longitude REAL,
  device_type TEXT NOT NULL DEFAULT 'other' CHECK (device_type IN ('phone', 'computer', 'other')),
  is_duplicate INTEGER NOT NULL DEFAULT 0 CHECK (is_duplicate IN (0, 1)),
  is_sender_suppressed INTEGER NOT NULL DEFAULT 0 CHECK (is_sender_suppressed IN (0, 1)),
  suppression_reason TEXT,
  FOREIGN KEY (email_id) REFERENCES tracked_emails(email_id)
);

Example response

{
  "id": 42,
  "email_id": "email_456",
  "user_id": "user_123",
  "recipient": "[email protected]",
  "opened_at": "2024-01-15T10:35:00.000Z",
  "ip_address": "203.0.113.42",
  "user_agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15",
  "geo_country": "United States",
  "geo_region": "California",
  "geo_city": "San Francisco",
  "latitude": 37.7749,
  "longitude": -122.4194,
  "device_type": "phone",
  "is_duplicate": 0,
  "is_sender_suppressed": 0,
  "suppression_reason": null
}

Build docs developers (and LLMs) love