SynapDocs

Entity connections

The two ways entities connect, structural links and semantic relations, and when to use each.

For BuildersOpen-source podSynap CloudReviewed 2026-11-04

Records in your pod connect to each other in two ways. A structural link is a field on a record that points to another record, such as the contact on a deal. A semantic relation is a typed edge in the pod's graph, such as a note that references a decision. You read both together, in one list.

The two systems

Structural linksSemantic relations
Stored asA field whose value is another record's id (valueType: "entity_id")A relation with a type, between two records
Defined byThe kind's fields, set up with the space or its templateAny time, by a person, an agent or an automation
DirectionFrom the record that holds the fieldReadable from either end
Good forThe core data model: "this deal's primary contact"Knowledge found later: "this note references that decision"

A structural link is a field of type entity_id on a kind. Its value is the id of another record. For example, a deal kind could have a contact field; every deal then shows it as a field people fill in.

Use a structural link when:

  • the link is part of what the record is, and most records of that kind have it;
  • you want it to appear as a field in forms;
  • the link has a clear direction ("a deal has one primary contact");
  • you are writing a template: model each relationship your kinds need as a field.

A field can also name a relation type. Writing that field then creates the matching relation in the graph, and clearing it removes the relation, so the link shows up in graph queries too.

Semantic relations

A semantic relation joins two records with a type, such as references, mentions or blocks. No field defines it: a person, an agent or an automation creates one between any two records when it finds the connection.

{
  "sourceEntityId": "<note-id>",
  "targetEntityId": "<decision-id>",
  "type": "references"
}

Use a semantic relation when:

  • the connection is found after the fact, not modelled up front;
  • it joins records of any kinds, with no field behind it;
  • you want to walk the graph, such as everything two hops from a record;
  • it is many-to-many and does not fit a field;
  • an agent is annotating what it found.

The type must be one the pod knows. Every pod has a set of default types, such as relates_to, references, mentions, parent_of, depends_on, blocks, assigned_to, created_by and works_at, and a space or its template can add its own. synap_list_profiles returns the relation types you may use.

When both could work

A deal could have a contact field, or a relates_to relation to the same person. The rule of thumb:

Use fields for what the kind's schema owns. Use relations for what you discover.

An assignee on a task is a field: it is part of the task. A references relation between two documents is a relation: it came from reading them.

One list of connections

GET /api/hub/entities/{id}/connections (scope hub-protocol.read) returns every connection around a record, from both systems and from the rest of the pod, in one list. Each item has a source:

sourceWhat it is
graphA semantic relation, with its relationType and a direction of outgoing or incoming
propertyA structural link, with its propertySlug and propertyLabel
threadA conversation that used, created, updated or referenced the record
context_channelA conversation about the record
focus_sessionA session whose subject is the record

The answer is { connections, counts }. limit caps the items read from each source (default 50, at most 200), and workspaceId reads through one space. The typed client wraps it: client.getConnections(entityId) from @synap-core/hub-rest-client.

GET /api/hub/relations reads only the graph, so a structural link whose field names no relation type is missing there. Use /connections when you want every link without knowing where it is stored.

For agents

  • Set a field when the link is a defined field (an assignee, the contact on a deal).
  • Create a relation for a connection you discover: synap_link_entities over MCP, or POST /api/hub/relations.
  • Read the connections to see every link around a record: GET /api/hub/entities/{id}/connections, or synap_get_relations over MCP for the graph edges alone.

On this page