The design challenge
Building data has traditionally been queried with SPARQL, a powerful graph query language that almost nobody outside academia uses. Tacit’s API design challenge was to preserve SPARQL’s three key capabilities while making them accessible through protocols developers already know.Three capabilities preserved
1. Class hierarchy inference
SPARQL usesa/rdfs:subClassOf* to match any subclass of a given type. Tacit exposes this through the is argument:
| SPARQL | Tacit GraphQL |
|---|---|
?x a/rdfs:subClassOf* brick:HVAC_Equipment | equipment(is: "HVAC_Equipment") |
?x a/rdfs:subClassOf* brick:Temperature_Sensor | points(is: "Temperature_Sensor") |
2. Transitive traversal
SPARQL usesbrick:feeds+ to follow relationship chains to any depth. Tacit exposes this through upstream and downstream fields:
| SPARQL | Tacit GraphQL |
|---|---|
?equip brick:feeds+ ?zone | zones { upstream { name type } } |
?zone ^brick:feeds+ ?source | equipment { downstream { name type } } |
3. Pattern matching
SPARQL uses triple patterns to describe relationship shapes. Tacit expresses patterns through nested GraphQL field selections:| SPARQL | Tacit GraphQL |
|---|---|
Multiple ?x ?rel ?y patterns | Nested field selections |
FILTER(STRSTARTS(...)) | is: "Temperature_Sensor" (Brick class filter) |
Combined patterns in WHERE clause | Combined nesting + filters |
What we chose not to preserve
Two SPARQL capabilities are deliberately excluded:- Cycle detection: finding circular relationships (A feeds B feeds C feeds A). These are rare in building data and indicate modeling errors rather than useful patterns.
- Arbitrary graph patterns: matching non-tree shapes where multiple variables connect in loops. These represent less than 1% of building queries and are not supported through the API.
Why GraphQL for reads
GraphQL was chosen over REST for the read surface because building queries are naturally hierarchical and variable-shaped:- Variable depth: equipment chains vary from 2 to 6 levels deep
- Variable breadth: one AHU might have 5 points, another might have 20
- Selective fields: one query needs just names, another needs values and timestamps
Why REST for management and timeseries
Resource management and historical data queries are simple, resource-oriented actions that map directly to HTTP verbs:GET /api/v1/sites/to list sitesPOST /api/v1/sites/to create a sitePOST /api/v1/sites/{id}/timeseriesto query historical timeseries data
Competitor approaches
| Company | Architecture | Limitation |
|---|---|---|
| Mapped | GraphQL only | No writes or control |
| Willow | REST only | Poor composability, multi-call queries |
| Cognite | REST + GraphQL | Generic industrial, no building semantics |
| DataGrid | Conversational AI | No deterministic queries |
Next steps
Quickstart
See the API in action.
GraphQL API
Start querying building data.
