SapixDBSapixDB/Docs
Home

Manual · Graph

Graph Index

SapixDB maintains a separate graph layer that stores typed directional edges between agents. Graph edges describe the structureof your data model — which agents relate to which — independently of the records stored in each agent's strand.

Graph edges vs. multi-agent joinsGraph edges are structural, schema-level links. They declare that one agent type relates to another and carry optional metadata about the relationship. They do not match individual records.

Multi-agent joins are data-level field matches. A join query scans the records of two agents at query time and pairs rows that share a field value.

Use graph edges to model your data hierarchy and drive traversal. Use joins when you need to correlate specific record values across agents. The two features are complementary.

Creating an edge

An edge is a directional, typed link from one agent to another. The edge_type is a free-form string you define — it describes the nature of the relationship.

HTTP
POST /v1/graph/edges
Authorization: Bearer spx_root_YOUR_ROOT_KEY
Content-Type: application/json

{
  "from_agent": "users",
  "to_agent":   "orders",
  "edge_type":  "has_orders",
  "meta": {
    "established": "2026-07-09"
  }
}
FieldRequiredDescription
from_agentYesAgent ID the edge originates from.
to_agentYesAgent ID the edge points to.
edge_typeYesA label describing the relationship (e.g. "has_orders", "belongs_to").
metaNoArbitrary JSON object stored alongside the edge.

Listing edges

Edges from an agent

HTTP
GET /v1/graph/edges?from=users
Authorization: Bearer spx_root_YOUR_ROOT_KEY

Returns all edges where from_agent is users — i.e. everything that users points to.

JSON response
{
  "edges": [
    {
      "from_agent": "users",
      "to_agent":   "orders",
      "edge_type":  "has_orders",
      "meta": { "established": "2026-07-09" }
    },
    {
      "from_agent": "users",
      "to_agent":   "profiles",
      "edge_type":  "has_profile",
      "meta": {}
    }
  ]
}

Edges to an agent

HTTP
GET /v1/graph/edges?to=orders
Authorization: Bearer spx_root_YOUR_ROOT_KEY

Returns all edges where to_agent is orders — i.e. which agents point to orders.

Deleting an edge

Delete a specific edge by specifying the from agent, to agent, and edge type in the URL path:

HTTP
DELETE /v1/graph/edges/users/orders/has_orders
Authorization: Bearer spx_root_YOUR_ROOT_KEY

Returns 204 No Content on success. Deleting an edge does not affect records stored in either agent.

Graph traversal

Traversal follows edges outward from a starting agent up to a specified hop depth. It returns all agents reachable within that depth along with the edge types connecting them.

HTTP
GET /v1/graph/traverse?from=users&depth=2
Authorization: Bearer spx_root_YOUR_ROOT_KEY
JSON response
{
  "origin": "users",
  "depth":  2,
  "nodes": [
    { "agent": "orders",    "via": "has_orders",    "hops": 1 },
    { "agent": "profiles",  "via": "has_profile",   "hops": 1 },
    { "agent": "shipments", "via": "has_shipments",  "hops": 2 }
  ]
}

With depth=2, the traversal visits direct neighbours (1 hop) and their neighbours (2 hops). Increasing depth follows longer paths but may return a large result set on densely connected graphs.

Traversal is breadth-firstTraversal visits each reachable agent once. If multiple paths lead to the same agent, it appears once in nodes at the shortest hop distance.

Record-level links

Edges can be scoped to specific records within agents by supplying from_record and to_record content hashes. This creates a link between individual records rather than between agents as a whole.

HTTP
POST /v1/graph/edges
Authorization: Bearer spx_root_YOUR_ROOT_KEY
Content-Type: application/json

{
  "from_agent":  "users",
  "to_agent":    "orders",
  "edge_type":   "placed",
  "from_record": "usr_hash_b3a7c2...",
  "to_record":   "order_hash_9d2e4f...",
  "meta": {
    "amount": 299.99
  }
}
FieldDescription
from_recordContent hash of the source record within from_agent.
to_recordContent hash of the target record within to_agent.

Record-level links are stored in the same graph layer as agent-level edges. They appear in GET /v1/graph/edges responses alongside agent-level edges. Traversal at depth=1 from an agent returns all agents it has edges to, regardless of whether those edges are record-level or agent-level.

Worked example — company hierarchy

Model a three-level hierarchy: a company has departments, and departments have employees.

Step 1 — create the edges

company → departments
POST /v1/graph/edges
{
  "from_agent": "company",
  "to_agent":   "departments",
  "edge_type":  "has_departments"
}
departments → employees
POST /v1/graph/edges
{
  "from_agent": "departments",
  "to_agent":   "employees",
  "edge_type":  "has_employees"
}

Step 2 — traverse from company at depth 2

HTTP
GET /v1/graph/traverse?from=company&depth=2
JSON response
{
  "origin": "company",
  "depth":  2,
  "nodes": [
    { "agent": "departments", "via": "has_departments", "hops": 1 },
    { "agent": "employees",   "via": "has_employees",   "hops": 2 }
  ]
}

Step 3 — link a specific employee to a specific department

Record-level link
POST /v1/graph/edges
{
  "from_agent":  "departments",
  "to_agent":    "employees",
  "edge_type":   "member",
  "from_record": "dept_hash_e4a1b2...",
  "to_record":   "emp_hash_7f3c9d...",
  "meta": { "joined": "2025-03-15" }
}

API reference

MethodPathAction
POST/v1/graph/edgesCreate an agent-level or record-level edge.
GET/v1/graph/edges?from=:agentList all edges originating from an agent.
GET/v1/graph/edges?to=:agentList all edges pointing to an agent.
DELETE/v1/graph/edges/:from/:to/:typeDelete a specific edge by from, to, and type.
GET/v1/graph/traverse?from=:agent&depth=:nBreadth-first traversal from an agent up to depth n.