curl -G 'https://api.hydradb.com/context/slack_C0BE77_1788320073/subgraph' \
-H "Authorization: Bearer <your_api_key>" \
-H "API-Version: 2" \
--data-urlencode "database=acme_corp" \
--data-urlencode "collection=eng_slack" \
--data-urlencode "depth=3"
hydradb subgraph slack_C0BE77_1788320073 --database acme_corp --collection eng_slack --depth 3
hydradb --output json subgraph slack_C0BE77_1788320073 | jq '.sources[].source_id'
{ "name": "hydradb_subgraph", "arguments": { "id": "slack_C0BE77_1788320073", "depth": 3 } }
{
"success": true,
"data": {
"seed_source_id": "slack_C0BE77_1788320073",
"sources": [
{
"source_id": "slack_C0BE77_1788320073",
"title": "Slack message",
"app_kind": "message",
"app_provider": "slack",
"app_external_id": "C0BE77TPEU8:1788320073.073799",
"thread_id": "C0BE77TPEU8:1788235712.185879",
"depth": 0,
"hydration": "resolved"
},
{
"source_id": "slack_C0BE77_1788235712",
"title": "Slack message",
"app_kind": "message",
"app_provider": "slack",
"app_external_id": "C0BE77TPEU8:1788235712.185879",
"thread_id": "C0BE77TPEU8:1788235712.185879",
"depth": 1,
"hydration": "resolved",
"discovered_via": "slack_C0BE77_1788320073",
"discovered_relation": "same_thread"
}
],
"relations": [
{
"source": { "name": "C0BE77TPEU8:1788320073.073799", "type": "SOURCE", "namespace": "sources", "entity_id": "slack_C0BE77_1788320073", "identifier": null },
"target": { "name": "C0BE77TPEU8:1788235712.185879", "type": "SOURCE", "namespace": "sources", "entity_id": "slack_C0BE77_1788235712", "identifier": null },
"relations": [
{ "canonical_predicate": "same_thread", "raw_predicate": "same_thread", "context": "", "confidence": 1, "temporal_details": null, "timestamp": "2026-09-02T03:34:33Z", "relationship_id": "rel_same_thread_1", "chunk_id": null, "source_entity_id": null, "target_entity_id": null }
],
"chunk_id": ""
}
],
"auxiliary_relations": [
{
"source": { "name": "saivenu", "type": "ACTOR", "namespace": "actors", "entity_id": "actor_saivenu", "identifier": "saivenu" },
"target": { "name": "C0BE77TPEU8:1788320073.073799", "type": "SOURCE", "namespace": "sources", "entity_id": "slack_C0BE77_1788320073", "identifier": null },
"relations": [
{ "canonical_predicate": "sender", "raw_predicate": "SENDER", "context": "", "confidence": 1, "temporal_details": null, "timestamp": "2026-09-02T03:34:33Z", "relationship_id": "rel_sender_1", "chunk_id": null, "source_entity_id": null, "target_entity_id": null }
],
"chunk_id": ""
}
],
"auxiliary_truncated": false,
"is_truncated": false,
"max_depth_reached": 1,
"success": true,
"message": "Subgraph fetched successfully"
},
"error": null,
"meta": {
"request_id": "9d13aef4-02f4-4e73-8c62-4c2601d04f9d",
"latency_ms": 41.7
}
}
{
"success": true,
"data": {
"seed_source_id": "no_such_item",
"sources": [],
"relations": [],
"auxiliary_relations": [],
"auxiliary_truncated": false,
"is_truncated": false,
"max_depth_reached": 0,
"success": true,
"message": "Subgraph fetched successfully"
},
"error": null,
"meta": {
"request_id": "9d13aef4-02f4-4e73-8c62-4c2601d04f9d",
"latency_ms": 6.1
}
}
{
"success": false,
"data": null,
"error": {
"code": "INVALID_INPUT",
"message": "depth must be a positive integer not exceeding 10"
},
"meta": {
"request_id": "9d13aef4-02f4-4e73-8c62-4c2601d04f9d",
"latency_ms": 0.4
}
}
Connected Subgraph
Everything connected to one item: its thread, its replies, its parents and children, and the items it links to.
curl -G 'https://api.hydradb.com/context/slack_C0BE77_1788320073/subgraph' \
-H "Authorization: Bearer <your_api_key>" \
-H "API-Version: 2" \
--data-urlencode "database=acme_corp" \
--data-urlencode "collection=eng_slack" \
--data-urlencode "depth=3"
hydradb subgraph slack_C0BE77_1788320073 --database acme_corp --collection eng_slack --depth 3
hydradb --output json subgraph slack_C0BE77_1788320073 | jq '.sources[].source_id'
{ "name": "hydradb_subgraph", "arguments": { "id": "slack_C0BE77_1788320073", "depth": 3 } }
{
"success": true,
"data": {
"seed_source_id": "slack_C0BE77_1788320073",
"sources": [
{
"source_id": "slack_C0BE77_1788320073",
"title": "Slack message",
"app_kind": "message",
"app_provider": "slack",
"app_external_id": "C0BE77TPEU8:1788320073.073799",
"thread_id": "C0BE77TPEU8:1788235712.185879",
"depth": 0,
"hydration": "resolved"
},
{
"source_id": "slack_C0BE77_1788235712",
"title": "Slack message",
"app_kind": "message",
"app_provider": "slack",
"app_external_id": "C0BE77TPEU8:1788235712.185879",
"thread_id": "C0BE77TPEU8:1788235712.185879",
"depth": 1,
"hydration": "resolved",
"discovered_via": "slack_C0BE77_1788320073",
"discovered_relation": "same_thread"
}
],
"relations": [
{
"source": { "name": "C0BE77TPEU8:1788320073.073799", "type": "SOURCE", "namespace": "sources", "entity_id": "slack_C0BE77_1788320073", "identifier": null },
"target": { "name": "C0BE77TPEU8:1788235712.185879", "type": "SOURCE", "namespace": "sources", "entity_id": "slack_C0BE77_1788235712", "identifier": null },
"relations": [
{ "canonical_predicate": "same_thread", "raw_predicate": "same_thread", "context": "", "confidence": 1, "temporal_details": null, "timestamp": "2026-09-02T03:34:33Z", "relationship_id": "rel_same_thread_1", "chunk_id": null, "source_entity_id": null, "target_entity_id": null }
],
"chunk_id": ""
}
],
"auxiliary_relations": [
{
"source": { "name": "saivenu", "type": "ACTOR", "namespace": "actors", "entity_id": "actor_saivenu", "identifier": "saivenu" },
"target": { "name": "C0BE77TPEU8:1788320073.073799", "type": "SOURCE", "namespace": "sources", "entity_id": "slack_C0BE77_1788320073", "identifier": null },
"relations": [
{ "canonical_predicate": "sender", "raw_predicate": "SENDER", "context": "", "confidence": 1, "temporal_details": null, "timestamp": "2026-09-02T03:34:33Z", "relationship_id": "rel_sender_1", "chunk_id": null, "source_entity_id": null, "target_entity_id": null }
],
"chunk_id": ""
}
],
"auxiliary_truncated": false,
"is_truncated": false,
"max_depth_reached": 1,
"success": true,
"message": "Subgraph fetched successfully"
},
"error": null,
"meta": {
"request_id": "9d13aef4-02f4-4e73-8c62-4c2601d04f9d",
"latency_ms": 41.7
}
}
{
"success": true,
"data": {
"seed_source_id": "no_such_item",
"sources": [],
"relations": [],
"auxiliary_relations": [],
"auxiliary_truncated": false,
"is_truncated": false,
"max_depth_reached": 0,
"success": true,
"message": "Subgraph fetched successfully"
},
"error": null,
"meta": {
"request_id": "9d13aef4-02f4-4e73-8c62-4c2601d04f9d",
"latency_ms": 6.1
}
}
{
"success": false,
"data": null,
"error": {
"code": "INVALID_INPUT",
"message": "depth must be a positive integer not exceeding 10"
},
"meta": {
"request_id": "9d13aef4-02f4-4e73-8c62-4c2601d04f9d",
"latency_ms": 0.4
}
}
depth hops, together with the relations among those members and the structural graph around them (entities, comments, attachments, people).
It answers a different question from Inspecting Context Relations. Relations are the entity-and-predicate triplets extracted from text (PaymentsWorker → depends_on → OrdersDB). The subgraph is about items: which Slack message replies to which, which page links to which, which ticket a comment belongs to. Use it after Query or List Documents when a single result is not enough and you need what surrounds it.
curl -G 'https://api.hydradb.com/context/slack_C0BE77_1788320073/subgraph' \
-H "Authorization: Bearer <your_api_key>" \
-H "API-Version: 2" \
--data-urlencode "database=acme_corp" \
--data-urlencode "collection=eng_slack" \
--data-urlencode "depth=3"
hydradb subgraph slack_C0BE77_1788320073 --database acme_corp --collection eng_slack --depth 3
hydradb --output json subgraph slack_C0BE77_1788320073 | jq '.sources[].source_id'
{ "name": "hydradb_subgraph", "arguments": { "id": "slack_C0BE77_1788320073", "depth": 3 } }
context.subgraph() with their next release, generated from this spec. Until then call the endpoint directly as above; the CLI and the MCP server already do.Path parameters
| Name | Description |
|---|---|
The item to start from. Any id returned by Query, List Documents or Ingest. URL-encode it if it contains reserved characters. An id containing a literal / cannot be written as one path segment; pass those as GET /context/subgraph?id=... instead. |
Query parameters
| Name | Description |
|---|---|
Owning database. Formerly tenant_id; the tenant_id alias is still accepted (deprecated). | |
Collection scope. If omitted, the default collection is used. Formerly sub_tenant_id; the sub_tenant_id alias is still accepted (deprecated). (default=null) | |
Which graph the id belongs to. The two graphs are completely separate. (default="knowledge") | |
Maximum traversal depth in hops. Range 1–10. (default=5) | |
Maximum number of members returned. Range 1–1000. When this clips the traversal, is_truncated is true. (default=200) | |
Principals to answer as (document ACLs). The subgraph then contains only items those principals may see, filtered at every hop. Repeated (acl=a&acl=b) or comma-separated. Omit for no ACL scoping. |
How items connect
Every member except the start item records how the traversal found it:discovered_relationnames the mechanism. It issame_threadwhen the member shares a thread with an item already in the subgraph (Slack replies, ticket comments);parentorchildfor a hierarchy tie (a comment and the message it is under, a page and its section); or the relation type of an explicitrelates_tolink declared at ingest (reply_to,references, whatever the ingest named it).discovered_viais thesource_idof the already-admitted member this one was first reached from. Follow it back and you rebuild the traversal tree: which reply hangs off which message, which page led to which.
depth on each member is its distance from the start item. The start item itself is a member at depth 0, with neither field set.
{
"success": true,
"data": {
"seed_source_id": "slack_C0BE77_1788320073",
"sources": [
{
"source_id": "slack_C0BE77_1788320073",
"title": "Slack message",
"app_kind": "message",
"app_provider": "slack",
"app_external_id": "C0BE77TPEU8:1788320073.073799",
"thread_id": "C0BE77TPEU8:1788235712.185879",
"depth": 0,
"hydration": "resolved"
},
{
"source_id": "slack_C0BE77_1788235712",
"title": "Slack message",
"app_kind": "message",
"app_provider": "slack",
"app_external_id": "C0BE77TPEU8:1788235712.185879",
"thread_id": "C0BE77TPEU8:1788235712.185879",
"depth": 1,
"hydration": "resolved",
"discovered_via": "slack_C0BE77_1788320073",
"discovered_relation": "same_thread"
}
],
"relations": [
{
"source": { "name": "C0BE77TPEU8:1788320073.073799", "type": "SOURCE", "namespace": "sources", "entity_id": "slack_C0BE77_1788320073", "identifier": null },
"target": { "name": "C0BE77TPEU8:1788235712.185879", "type": "SOURCE", "namespace": "sources", "entity_id": "slack_C0BE77_1788235712", "identifier": null },
"relations": [
{ "canonical_predicate": "same_thread", "raw_predicate": "same_thread", "context": "", "confidence": 1, "temporal_details": null, "timestamp": "2026-09-02T03:34:33Z", "relationship_id": "rel_same_thread_1", "chunk_id": null, "source_entity_id": null, "target_entity_id": null }
],
"chunk_id": ""
}
],
"auxiliary_relations": [
{
"source": { "name": "saivenu", "type": "ACTOR", "namespace": "actors", "entity_id": "actor_saivenu", "identifier": "saivenu" },
"target": { "name": "C0BE77TPEU8:1788320073.073799", "type": "SOURCE", "namespace": "sources", "entity_id": "slack_C0BE77_1788320073", "identifier": null },
"relations": [
{ "canonical_predicate": "sender", "raw_predicate": "SENDER", "context": "", "confidence": 1, "temporal_details": null, "timestamp": "2026-09-02T03:34:33Z", "relationship_id": "rel_sender_1", "chunk_id": null, "source_entity_id": null, "target_entity_id": null }
],
"chunk_id": ""
}
],
"auxiliary_truncated": false,
"is_truncated": false,
"max_depth_reached": 1,
"success": true,
"message": "Subgraph fetched successfully"
},
"error": null,
"meta": {
"request_id": "9d13aef4-02f4-4e73-8c62-4c2601d04f9d",
"latency_ms": 41.7
}
}
{
"success": true,
"data": {
"seed_source_id": "no_such_item",
"sources": [],
"relations": [],
"auxiliary_relations": [],
"auxiliary_truncated": false,
"is_truncated": false,
"max_depth_reached": 0,
"success": true,
"message": "Subgraph fetched successfully"
},
"error": null,
"meta": {
"request_id": "9d13aef4-02f4-4e73-8c62-4c2601d04f9d",
"latency_ms": 6.1
}
}
{
"success": false,
"data": null,
"error": {
"code": "INVALID_INPUT",
"message": "depth must be a positive integer not exceeding 10"
},
"meta": {
"request_id": "9d13aef4-02f4-4e73-8c62-4c2601d04f9d",
"latency_ms": 0.4
}
}
Reading the response
sources[]are the members, the start item included atdepth: 0. Everysource_idis an id you can pass to Fetch Content for the full document, or back to this endpoint to re-centre the subgraph on it.discovered_viaon each member is another member’ssource_id, so the list is also a tree.relations[]are the item-level relations among the members (relates_to,same_thread,parent_of), in the same triplet shape as Inspecting Context Relations. Their endpoints areSOURCEentities whoseentity_idis the item’s id.auxiliary_relations[]is the structural graph around the members: which person sent a message, which entities are mentioned in it, which comments and attachments hang off it. These are recorded from the item itself, not extracted from text, so theircontextis empty.- Not included: the chunk-level entity relations that Query returns as
graph_context. Those are a different read.
Some additional notes
id is an empty subgraph, not an error. The endpoint does not confirm or deny that an item exists; the same answer comes back for an id that was never ingested and for one the acl principals may not see.- An item nothing links to comes back as a one-member subgraph: itself, at depth
0, withmax_depth_reached: 0. That is a real answer (“this stands alone”), distinct from an unknown id, which has no members. - Bounding the traversal. Threads and hierarchies can be large.
depthbounds how far the walk goes;max_sourcesbounds how many members it returns. Whenmax_sourcesclips it,is_truncatedistrueand the members you have are the ones closest to the start item.auxiliary_truncatedreports the same for the structural graph. - Knowledge vs memory. If the
idbelongs to a memory, settype=memory; the two graphs never connect to each other. - Completeness. An item’s links populate once its
indexing_statusreachescompleted. Items still ingraph_creationmay appear with fewer connections than they will have. - Cost. One request fans out into a bounded series of graph reads, so it is rate-limited like a Query, not like a status poll.
- Entity relations: Inspecting Context Relations - the triplets extracted from text
- Full content of a member: Fetch Content
- Query with graph context: Query with
graph_context: true - Concepts: Concepts → Context Graphs
Authorizations
API key sent as a Bearer token: "Bearer prefix.secret"
Path Parameters
Item ID: the ingested item whose connected subgraph to return. URL-encode it. An id containing a literal '/' cannot be spelled as one path segment; address those with the query form, GET /context/subgraph?id=.
"HydraDoc1234"
Query Parameters
Database (canonical name for the tenant scope)
"acme_corp"
Collection (canonical name for the sub-tenant scope)
"team_docs"
Deprecated alias for database
"tenant_1234"
Deprecated alias for collection
"sub_tenant_4567"
Corpus type: 'knowledge' or 'memory'
knowledge, memory Max traversal depth in hops
1 <= x <= 10Max members returned; is_truncated reports when this clipped the traversal
1 <= x <= 1000Principals to answer as (document ACLs): the subgraph contains only items they may see, filtered at every hop. Repeated (acl=a&acl=b) or comma-separated. Omit for no ACL scoping.
Response
OK
Show child attributes
Show child attributes
{
"auxiliary_relations": [
{
"chunk_id": "HydraEmbeddings123_0",
"relations": [
{
"canonical_predicate": "works_at",
"chunk_id": "HydraEmbeddings123_0",
"confidence": 0.92,
"context": "Ada joined Acme Corp in 2024 as a staff engineer.",
"raw_predicate": "is employed by",
"relationship_id": "rel_1234",
"source_entity_id": "entity_1a2b",
"synthesized": true,
"target_entity_id": "entity_3c4d",
"temporal_details": "since 2024",
"timestamp": "2026-07-02T10:00:00Z"
}
],
"source": {
"entity_id": "entity_1a2b",
"identifier": "Acme Corp",
"name": "general",
"namespace": "organization",
"provider": "slack",
"type": "knowledge"
},
"target": {
"entity_id": "entity_1a2b",
"identifier": "Acme Corp",
"name": "general",
"namespace": "organization",
"provider": "slack",
"type": "knowledge"
},
"truncated": true
}
],
"auxiliary_truncated": true,
"is_truncated": false,
"max_depth_reached": 1,
"message": "Success",
"relations": [
{
"chunk_id": "HydraEmbeddings123_0",
"relations": [
{
"canonical_predicate": "works_at",
"chunk_id": "HydraEmbeddings123_0",
"confidence": 0.92,
"context": "Ada joined Acme Corp in 2024 as a staff engineer.",
"raw_predicate": "is employed by",
"relationship_id": "rel_1234",
"source_entity_id": "entity_1a2b",
"synthesized": true,
"target_entity_id": "entity_3c4d",
"temporal_details": "since 2024",
"timestamp": "2026-07-02T10:00:00Z"
}
],
"source": {
"entity_id": "entity_1a2b",
"identifier": "Acme Corp",
"name": "general",
"namespace": "organization",
"provider": "slack",
"type": "knowledge"
},
"target": {
"entity_id": "entity_1a2b",
"identifier": "Acme Corp",
"name": "general",
"namespace": "organization",
"provider": "slack",
"type": "knowledge"
},
"truncated": true
}
],
"sources": [
{
"app_external_id": "C0123456789",
"app_kind": "slack",
"app_provider": "slack",
"depth": 1,
"source_id": "HydraDoc1234",
"title": "Project Phoenix Overview"
}
],
"success": true
}
Error message, empty string on success.
Show child attributes
Show child attributes
{
"code": "DATABASE_NOT_FOUND",
"message": "Database not found"
}
Show child attributes
Show child attributes
{
"collection": "team_docs",
"database": "acme_corp",
"latency_ms": 12.3,
"request_id": "9d13aef4-02f4-4e73-8c62-4c2601d04f9d",
"source_type": "file",
"sub_tenant_id": "sub_tenant_4567",
"tenant_id": "tenant_1234"
}
Whether the request succeeded.
true
Was this page helpful?
