Skip to main content

Endpoint

POST /api/v1/sites/{siteId}/insights/ingest/
Submit a fault detection finding, energy optimization suggestion, or maintenance alert from an external system. Tacit automatically deduplicates repeated detections of the same condition.
This endpoint requires an API key with the insights:write scope. See Authentication for details on creating and using API keys.

Path parameters

ParameterTypeDescription
siteIdstringSite slug (e.g., ucl-east-ops)

Request body

FieldTypeRequiredDescription
sourcestringYesSystem that generated this insight (e.g., altotech, rule_engine, honeywell_bms)
source_idstringYesUnique identifier for this finding within the source. Used as the deduplication key together with source
titlestringYesHuman-readable summary of the finding
severitystringYesOne of: critical, warning, info
categorystringYesOne of: fault, comfort, energy, maintenance
bodystringNoDetailed description of the finding. Supports Markdown with entity links
equipment_uristringNoEquipment ID from the knowledge graph (e.g., PD00-XX-AHU-001). Omit for multi-equipment or building-wide insights
timeseries_idsstring[]NoList of timeseries UUIDs that support this finding. Get these from the GraphQL point.timeseriesId field
analysisobjectNoArbitrary JSON with source-specific context (thresholds, readings, confidence scores)
occurred_atstringNoISO-8601 timestamp of when the condition started. Defaults to detection time
The body field supports Markdown. When rendered in the Tacit UI, special link schemes create interactive navigation elements. Link to equipment, zones, or points in the knowledge graph. These render as clickable chips with a popover offering navigation to the Twin View, Asset detail, and historical chart.
[Equipment Name](entity:EQUIPMENT-ID?type=equipment&class=BrickClass)
ParameterRequiredDescription
typeNoEntity type: equipment, point, zone, floor, building, system, location. Defaults to equipment
classNoBrick class name (e.g., AHU, FCU, Heat_Exchanger). Shown in the popover header
ifcNoIFC GUID for 3D model highlighting
tsNoTimeseries UUID for a direct link to the historical chart
Example:
[Podium GF AHU 1](entity:PD00-XX-AHU-001?type=equipment&class=AHU) is reporting
**Critical_Alarm = 1**. Immediate investigation required.
Cross-reference other insights or work orders. These render as standard links that navigate to the detail page.
[Related insight title](insight:INSIGHT-UUID)
[Related work order title](workorder:WORKORDER-UUID)

Multi-equipment insights

For insights that span multiple pieces of equipment, omit equipment_uri and list affected equipment as entity links in the body:
All four FCUs in Common Room 3 have heating valves fully open at 100%.

Affected equipment:
- [Common Room 3 FCU 1](entity:TE03-CM3-FCU-001?type=equipment&class=FCU)
- [Common Room 3 FCU 2](entity:TE03-CM3-FCU-002?type=equipment&class=FCU)
- [Common Room 3 FCU 3](entity:TE03-CM3-FCU-003?type=equipment&class=FCU)
- [Common Room 3 FCU 4](entity:TE03-CM3-FCU-004?type=equipment&class=FCU)

Response

Both 201 and 200 responses return the full insight object:
FieldTypeDescription
idstringUUID of the insight
sitestringSite ID
titlestringFinding title
bodystringDetailed description (Markdown)
statusstringactive, resolved, or dismissed
severitystringcritical, warning, or info
categorystringfault, comfort, energy, or maintenance
sourcestringOriginating system
source_idstringSource’s reference ID
equipment_uristringEquipment ID
equipment_namestringResolved equipment name from the knowledge graph
timeseries_idsstring[]Supporting timeseries UUIDs
analysisobjectSource-specific context
detected_atstringISO-8601 timestamp of first detection
last_seen_atstringISO-8601 timestamp of most recent detection
detection_countintegerTotal number of times this condition was detected
occurred_atstring | nullWhen the condition started (if provided)
resolved_atstring | nullWhen the insight was resolved or dismissed

Deduplication

Tacit uses the combination of site + source + source_id as a fingerprint. When you submit an insight:
  • If no active insight matches the fingerprint, a new insight is created (HTTP 201)
  • If an active insight already matches, it is treated as a re-detection (HTTP 200). The existing insight’s last_seen_at timestamp is updated, its detection_count is incremented, and the analysis field is replaced with the latest data
Resolved or dismissed insights are never reopened. If the same condition reappears after resolution, a new insight is created.

Status codes

CodeDescription
201New insight created
200Existing insight updated (re-detection)
400Validation error (missing required fields, invalid severity/category)
401Not authenticated
403No access to this site, or API key missing insights:write scope
404Site not found
429Rate limit exceeded. Check the Retry-After header

Examples

Single-equipment fault

curl -X POST https://app.tacitwin.ai/api/v1/sites/ucl-east-ops/insights/ingest/ \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "source": "rule_engine",
    "source_id": "g36-fc5:ahu-01",
    "title": "AHU-01 supply air temperature drifting above setpoint",
    "severity": "warning",
    "category": "fault",
    "body": "[AHU-01](entity:PD00-XX-AHU-001?type=equipment&class=AHU) supply air temperature has exceeded setpoint by 2.3°C for the past 6 hours.",
    "equipment_uri": "PD00-XX-AHU-001",
    "timeseries_ids": [
      "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "7c9e6679-7425-40de-944b-e07fc1f90ae7"
    ],
    "analysis": {
      "rule_id": "G36-FC5",
      "supply_air_temp": 22.3,
      "setpoint": 20.0,
      "cooling_valve_position": 0.87
    },
    "occurred_at": "2026-03-15T04:00:00Z"
  }'
Response (201)
{
  "id": "e8b3c2a1-7d4f-4e6b-a9c8-2d1f3e5a7b9c",
  "site": "ucl-east-ops",
  "title": "AHU-01 supply air temperature drifting above setpoint",
  "body": "[AHU-01](entity:PD00-XX-AHU-001?type=equipment&class=AHU) supply air temperature has exceeded setpoint by 2.3°C for the past 6 hours.",
  "status": "active",
  "severity": "warning",
  "category": "fault",
  "source": "rule_engine",
  "source_id": "g36-fc5:ahu-01",
  "equipment_uri": "PD00-XX-AHU-001",
  "equipment_name": "Podium GF AHU 1",
  "timeseries_ids": [
    "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "7c9e6679-7425-40de-944b-e07fc1f90ae7"
  ],
  "analysis": {
    "rule_id": "G36-FC5",
    "supply_air_temp": 22.3,
    "setpoint": 20.0,
    "cooling_valve_position": 0.87
  },
  "detected_at": "2026-03-15T08:15:00Z",
  "last_seen_at": "2026-03-15T08:15:00Z",
  "detection_count": 1,
  "occurred_at": "2026-03-15T04:00:00Z",
  "resolved_at": null
}

Re-detection of the same condition

Submitting the same source + source_id again while the insight is still active:
Request
{
  "source": "rule_engine",
  "source_id": "g36-fc5:ahu-01",
  "title": "AHU-01 supply air temperature drifting above setpoint",
  "severity": "warning",
  "category": "fault",
  "analysis": {
    "rule_id": "G36-FC5",
    "supply_air_temp": 23.1,
    "setpoint": 20.0,
    "cooling_valve_position": 0.92
  }
}
Response (200)
{
  "id": "e8b3c2a1-7d4f-4e6b-a9c8-2d1f3e5a7b9c",
  "detection_count": 2,
  "last_seen_at": "2026-03-15T10:47:00Z",
  "analysis": {
    "rule_id": "G36-FC5",
    "supply_air_temp": 23.1,
    "setpoint": 20.0,
    "cooling_valve_position": 0.92
  }
}
Notice detection_count incremented to 2, last_seen_at updated, and analysis replaced with the latest readings. The id and detected_at remain unchanged.
Request
{
  "source": "claude-analysis",
  "source_id": "ucl-ops-2026-04-01-common-room-3-heat-valves",
  "title": "Common Room 3 — all 4 FCU heating valves at 100%",
  "severity": "warning",
  "category": "comfort",
  "body": "All four FCUs in Common Room 3 have their heating valves fully open at 100%.\n\nAffected equipment:\n- [Common Room 3 FCU 1](entity:TE03-CM3-FCU-001?type=equipment&class=FCU)\n- [Common Room 3 FCU 2](entity:TE03-CM3-FCU-002?type=equipment&class=FCU)\n- [Common Room 3 FCU 3](entity:TE03-CM3-FCU-003?type=equipment&class=FCU)\n- [Common Room 3 FCU 4](entity:TE03-CM3-FCU-004?type=equipment&class=FCU)\n\nInvestigate actuators and LTHW supply.",
  "timeseries_ids": [
    "736bac96-0c6f-5cb2-becd-9b2a600607ac",
    "216ad4b3-6a9b-5995-b889-5d61dbd06e0a",
    "65902354-2a9a-5080-bfe7-7d602038f42b",
    "0f0790da-cd31-546d-bcc7-41e00767d93b"
  ],
  "occurred_at": "2026-04-01T16:17:00+01:00"
}
Note: No equipment_uri — the affected equipment is referenced via entity links in the body instead.

Source and source ID conventions

The source field identifies the system that generated the finding. Use a consistent, lowercase identifier:
System typeExample sourceExample source_id
External FDD vendoraltotechALT-FAULT-98234 (vendor’s internal reference)
Internal rule enginerule_engineg36-fc5:ahu-01 (rule ID + equipment)
BMS alarm forwardinghoneywell_bmsBMS-ALM-44521
AI analysisclaude-analysissite-date-equipment-type
The combination of source + source_id must be unique per active insight within a site. Different sources can use the same source_id format independently.