Browse the knowledge graph from a node
Changed onOpen a node in the knowledge graph and see what is inside it — a file explorer across every connected source.
Call it with no nodeId for a flat listing of every record group and record the caller can reach, newest first. This is a starting point to pick a node from, not a roster of connected apps — app nodes are not returned in a listing (except at the root of a limited connected app, below), though an app's id is accepted as a nodeId and lists that app's record groups. Pass a node's id to descend: record groups contain records and folders, and a record contains its own children — comments, attachments, sub-tasks — plus a related section of cross-referenced records, such as the Confluence page linked from a Jira ticket. nodeId is tolerant: a URL or an issue key such as PA-1787 is resolved to its record before navigating, so a link can be pasted straight in without a separate lookup call.
The response carries a rendered text view — breadcrumbs, the current node, the children listing, Related:, and a closing Next: line naming a follow-up call. The structured fields carry the same information for programmatic use.
When to use this vs. the other record endpoints:
- This endpoint is for structural exploration — "what is in this project", "what is attached to this ticket", "what else links to this page". It returns names, types and IDs; it never returns document text.
- GET /connectors/record/{recordId}/content returns one record's actual parsed text. Use it once navigation has identified the record you want to read.
- GET /connectors/record/lookup is the way in when you hold a URL or an issue key rather than a position in the tree.
Typical flow: call with no nodeId to see what is reachable → pass a record group's id to list its records → take a row whose is_record is true and call GET /connectors/record/{recordId}/content to read it.
Paging and depth: results are paginated; pagination.has_next tells you whether to request the next page. depth above 1 returns all descendants down to that level as one flat list, each row carrying its own level, instead of only direct children.
Scope: everything the caller can read, across both connectors and Knowledge Base collections. No connector-level filter is applied — the listing is bounded by per-node permissions, and for a connected app with a limit by that limit too: no row, breadcrumb or related node outside it is returned.
A connected app with a limit: with no nodeId, the root depends on what the limit names.
- Whole sources (apps or collections) only: the usual flat root, every record group and record in those sources.
- Any spaces, folders or files, alone or beside whole sources: one row for each whole source, space (record group), folder and file the limit names, and nothing from inside them. pagination.total counts those rows, not the records inside them. depth is not applied on this call; pass a row's id as nodeId to open it.
Permission scoping:
rows and related carry only nodes the caller can see, and the opened node itself is access-checked before any of its details are returned. A node that does not exist and a node the caller cannot access are deliberately indistinguishable — both return an empty view rather than an error.
breadcrumbs is the exception: the ancestor trail is resolved by id alone, without a permission check. For a record shared directly with the caller, it can therefore name ancestors the caller cannot open. Treat breadcrumb entries as labels, not as nodes guaranteed to be navigable.
A connected app with a limit: the opened record's context_block, and each row's context_summary, names nothing outside the limit beside the record. Its External Parent ID reads N/A for a parent the limit leaves out, and a code file's Path: line is left out unless the limit covers the whole app. Linked records, related tables, a deal's orgs and products, and live Jira parent, epic, sub-task and linked-issue lines appear only for records inside the limit. Web URL is kept, though it can contain folder names.
Connector and knowledge base nodes: opening the id of a connector instance the caller has no permission on in the graph (for example one that has never synced, even for its creator) returns the same empty view as a missing node. Opening a knowledge base at depth 1 lists nothing; its records appear from depth 2.
An OAuth token holding connector:read instead of kb:read is accepted too.
Request
- Base URLhttps://app.pipeshub.com/api/v1
- URLhttps://app.pipeshub.com/api/v1/connectors/navigate
- Auth
- HTTP bearer
- or OAuth 2Authorization code: /api/v1/oauth2/authorizeClient credentialsToken URL: /api/v1/oauth2/token scopes: kb:read
Query parameters
The node to open. Take it from an id in a previous navigate or lookup response. Omit it entirely for the flat listing of everything reachable — the usual starting point. A URL or an issue key such as PA-1787 also works: it is resolved to its record automatically. The value is trimmed before it is checked, so a blank one is refused like an empty one.
Page number, 1-indexed.
Children per page. The minimum is 50 — smaller values are rejected rather than silently raised.
Levels of descendants to return in one call. Above 1, rows is a flat list of all descendants down to that level rather than only direct children, and each row carries its own level.
Restrict children to these node types. Repeat the parameter for multiple types: ?nodeTypes=record&nodeTypes=folder. A single value is read as a list of one. The types that filter are app, recordGroup, record and folder; any other value is accepted and ignored, so it does not narrow the listing.
A date filter of GET /connectors/navigate: YYYY-MM-DD (UTC; start of the day for a lower bound, end of the day for an upper bound), or a date and time with a timezone offset (Z or ±HH:MM). Empty, blank or timezone-naive values are refused with 400.
Filter children by source creation time. ISO 8601 YYYY-MM-DD, or a full datetime that MUST carry a timezone offset — a naive datetime is rejected rather than assumed to be UTC. Must not be in the future (5 minutes of clock skew are tolerated) and must not be after createdBefore. A YYYY-MM-DD day past the end of its month (2024-02-31) counts from the first day of the next month here, and as the month's last day in a ...Before bound. A day above 31, a month above 12 or year 0 (2024-02-32) is refused with 400.
A date filter of GET /connectors/navigate: YYYY-MM-DD (UTC; start of the day for a lower bound, end of the day for an upper bound), or a date and time with a timezone offset (Z or ±HH:MM). Empty, blank or timezone-naive values are refused with 400.
Filter children by source creation time. YYYY-MM-DD is inclusive of the whole day.
A date filter of GET /connectors/navigate: YYYY-MM-DD (UTC; start of the day for a lower bound, end of the day for an upper bound), or a date and time with a timezone offset (Z or ±HH:MM). Empty, blank or timezone-naive values are refused with 400.
Filter children by source modification time. Must not be after modifiedBefore.
A date filter of GET /connectors/navigate: YYYY-MM-DD (UTC; start of the day for a lower bound, end of the day for an upper bound), or a date and time with a timezone offset (Z or ±HH:MM). Empty, blank or timezone-naive values are refused with 400.
Filter children by source modification time. YYYY-MM-DD is inclusive of the whole day.
Response
Successful operation. A node that does not exist or is not accessible returns an empty view (null current, empty rows) rather than an error.
Changes
- breaking
added the pattern
\Sto thequeryrequest parameternodeId - breaking
added the pattern
^\d{4}-\d{2}-\d{2}([T ]\d{2}(:\d{2}(:\d{2}([.,]\d+)?)?)?([Zz]|[+-]\d{2}(:?\d{2})?))?$to thequeryrequest parametercreatedAfter - breaking
added the pattern
^\d{4}-\d{2}-\d{2}([T ]\d{2}(:\d{2}(:\d{2}([.,]\d+)?)?)?([Zz]|[+-]\d{2}(:?\d{2})?))?$to thequeryrequest parametercreatedBefore - breaking
added the pattern
^\d{4}-\d{2}-\d{2}([T ]\d{2}(:\d{2}(:\d{2}([.,]\d+)?)?)?([Zz]|[+-]\d{2}(:?\d{2})?))?$to thequeryrequest parametermodifiedAfter - breaking
added the pattern
^\d{4}-\d{2}-\d{2}([T ]\d{2}(:\d{2}(:\d{2}([.,]\d+)?)?)?([Zz]|[+-]\d{2}(:?\d{2})?))?$to thequeryrequest parametermodifiedBefore - info
the security scope
kb:readwas added to the endpoint's security schemeoauth2 - info
the security scope
connector:readwas removed from the endpoint's security schemeoauth2
- breaking
- info
added the optional property
/to the response with the status - info
added the optional property
/to the response with the status - info
added the optional property
/to the response with the status - info
added the optional property
/to the response with the status - info
added the optional property
/to the response with the status - info
added the optional property
/to the response with the status
- info