Skip to content

Collector API ​

The HealthGuard Collector provides REST APIs for SDK event ingestion and Dashboard data queries.

Base URL: http://your-collector-host:3100

POST /api/events/batch ​

Batch event ingestion endpoint. The SDK calls this endpoint to report captured events.

Request ​

json
{
  "appKey": "web_abc123",
  "events": [
    {
      "eventId": "evt_xxx",
      "appKey": "web_abc123",
      "platform": "web",
      "type": "error",
      "timestamp": 1716192000000,
      "sessionId": "session_xxx",
      "anonymousId": "anon_xxx",
      "sdkVersion": "0.1.0",
      "errorType": "js",
      "message": "Cannot read property 'foo' of undefined",
      "stack": "...",
      "fingerprint": "js:abc123",
      "breadcrumbs": []
    }
  ]
}

Response ​

json
{
  "accepted": 1
}

Fields ​

FieldTypeRequiredDescription
appKeystringYesUnique app identifier
eventsarrayYesEvent array, min 1, max 50 items

POST /api/auth/register ​

User registration.

Request ​

json
{
  "email": "user@example.com",
  "password": "your-password"
}

Response ​

json
{
  "token": "session_xxx",
  "user": {
    "id": "user_xxx",
    "email": "user@example.com",
    "createdAt": 1716192000000
  }
}

POST /api/auth/login ​

User login.

Request ​

Same as /api/auth/register.

Response ​

Same as /api/auth/register.

GET /api/auth/me ​

Get current user info.

Headers ​

Authorization: Bearer <token>

GET /api/apps ​

List apps for the current user.

Headers ​

Authorization: Bearer <token>

POST /api/apps ​

Create a new app.

Headers ​

Authorization: Bearer <token>

Request ​

json
{
  "name": "My Web App",
  "type": "web"
}

GET /api/overview ​

Get data overview.

Query Parameters ​

ParameterTypeRequiredDescription
appKeystringNoFilter by app

Response ​

json
{
  "totals": {
    "events": 128,
    "errors": 12,
    "failedRequests": 3,
    "affectedUsers": 8,
    "issues": 5
  }
}

GET /api/issues ​

List issues.

Query Parameters ​

ParameterTypeRequiredDescription
appKeystringNoFilter by app

GET /api/issues/:id ​

Get issue details.

Response ​

json
{
  "issue": {
    "id": "web_abc123:js:def456",
    "appKey": "web_abc123",
    "fingerprint": "js:def456",
    "message": "Cannot read property 'foo' of undefined",
    "errorType": "js",
    "eventCount": 15,
    "firstSeenAt": 1716100000000,
    "lastSeenAt": 1716192000000
  },
  "events": [...]
}

PATCH /api/apps/:appKey ​

Updates the display name using the project owner's Authorization: Bearer <SESSION_TOKEN>.

json
{ "name": "Example driver" }

Accepts only name, containing 1–100 characters after trimming. Returns { "app": { ... } } with id, name, appKey, type and createdAt. Errors: 401 unauthenticated; 400 INVALID_APP_NAME invalid fields/name; 404 APP_NOT_FOUND absent or not owned by the caller.

Updates only the name. App keys, historical data and notification rules remain unchanged. No schema migration or SDK upgrade is required; older Collectors must be upgraded first.

PATCH /api/issues/:id/archive ​

Requires the project owner’s bearer session. Unverified issues may be archived; no code repair is executed.

json
{ "note": "Server-side fix completed" }

The body and note may be omitted. Notes are trimmed and limited to 4000 characters; invalid types, unknown fields or excessive length return 400. Unauthenticated requests return 401; missing or unowned issues return 404. Returns { issue } with archiveRecord: { note, archivedAt }; timestamps are milliseconds. Duplicate requests preserve the saved archive record. New events remain counted without reopening manual archives.

PATCH /api/issues/:id/reopen ​

Only the project owner may restore an issue. Returns it to Current issues while retaining the previous archive note; no application code changes. Collector startup adds issues.archive_record JSONB without deleting historical repair metadata. Deploy Collector before Dashboard.

Retained lifecycle and PR write APIs also enforce project ownership, preventing legacy calls from bypassing archive permissions.

Event receipt and notification clocks ​

Issue detail events include nullable receivedAt (Unix milliseconds), set by the Collector at the batch boundary. Client-supplied values are ignored; timestamp remains client-reported occurrence time. Duplicate Event IDs retain first receipt and counts. Historical rows return null without inferring receipt from insertion, event or mail times; existing ordering and filters retain occurrence-time semantics.

Notification history adds eventTimestamp, receivedAt, sendingStartedAt and sentAt; createdAt remains job creation time. Processing start precedes configuration and connection work. sentAt is only set after successful SMTP acceptance and is null for failed, canceled or unknown delivery; neither confirms inbox placement. Unrecorded historical fields may be absent/null and test messages have no event time. Migration adds nullable events.received_at only; retain it on rollback.

Device fields and owner-only queries (Unreleased) ​

Flutter 0.3.0 adds independent deviceId (hgd1_ plus 64 SHA-256 hex characters), deviceIdStatus, deviceIdSource, deviceIdScope, and unavailable deviceIdReason. Model/OS use deviceInfo.model/system; event App/SDK versions use release/sdkVersion. Lookup failure omits deviceId; legacy events remain accepted and unknown. Collector validates format and consistent identity metadata, persists fields in existing JSONB and adds a project/time index without historical ID backfill.

Project-owner Bearer sessions can call:

  • GET /api/devices?appKey=<KEY>&kind=stable&search=HG-...&limit=50&offset=0
  • GET /api/devices/events?appKey=<KEY>&key=<URL_ENCODED_FULL_GROUP_KEY>&limit=50&offset=0

Optional platform/start/end filters use millisecond timestamps. Kinds are stable/installation/unknown; page size is 1–100. Lists return devices/total/totals, with stableDevices/installations/unidentifiedEvents; history returns events/total. Category totals cover the platform/time range; list total also applies kind/search. Use the returned full group key for history, never a shortcode. Unauthenticated requests return 401; absent or foreign-owned projects return 404. Counts describe retained anomaly data, not a permanent physical fleet registry.

Released under the MIT License.