Skip to main content

GET /api/analytics/vector-graph

Fetches all Qdrant vector points belonging to a user (up to 100), validates them against Appwrite Storage to filter out orphaned vectors, reduces their 768-dimension embeddings to 2D coordinates using UMAP, and returns graph nodes and edges ready for a force-directed visualisation. Sequential chunks from the same document are connected as edges so that document clusters are visible in the rendered graph.
UMAP requires at least 2 points to produce a projection. If the user has no indexed documents the endpoint returns empty nodes and links arrays without an error.

Query parameters

userId
string
required
Appwrite user ID. Only vectors with a matching userId payload field are included.
cleanup
string
default:"false"
Set to "true" to delete Qdrant vectors whose documentId no longer exists in Appwrite Storage before building the graph. Useful for removing orphaned vectors after files are deleted outside of /api/documents/delete.

Response

{
  "nodes": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "x": 123.45,
      "y": -67.89,
      "documentId": "file_abc123",
      "fileName": "report.pdf",
      "documentType": "PDF",
      "category": "finance",
      "chunkIndex": 0,
      "chunkText": "Revenue grew 12% year-over-year…",
      "uploadDate": "2024-11-01T10:00:00.000Z"
    }
  ],
  "links": [
    { "source": "550e8400-…", "target": "660f9511-…" }
  ],
  "totalDocuments": 1,
  "totalChunks": 14,
  "unusedVectors": 0,
  "cleanedUp": false,
  "documentGroups": [
    {
      "documentId": "file_abc123",
      "fileName": "report.pdf",
      "chunkCount": 14
    }
  ]
}
nodes
object[]
One node per valid vector point. Coordinates are normalised to the range [-200, 200] on both axes.
Edges connecting consecutive chunks within the same document. Chunks are sorted by chunkIndex before edges are created.
totalDocuments
number
Number of unique document file names represented in the graph.
totalChunks
number
Total number of nodes (valid vector points).
unusedVectors
number
Number of Qdrant vectors whose documentId was not found in Appwrite Storage. Non-zero only when orphaned vectors exist.
cleanedUp
boolean
true if cleanup=true was requested and orphaned vectors were deleted.
documentGroups
object[]
Summary of each document’s chunk count, useful for building a legend.

Empty state

When the user has no indexed documents, or all vectors are orphaned and cleanup is not set, the endpoint returns:
{
  "nodes": [],
  "links": [],
  "totalDocuments": 0,
  "totalChunks": 0,
  "message": "No documents found"
}

Errors

StatusCondition
400userId query parameter is missing
500QDRANT_CLUSTER_URL or QDRANT_API_KEY environment variables are not set
500Appwrite Storage file listing failed
500UMAP projection failed

Example

curl "https://<your-prism-domain>/api/analytics/vector-graph?userId=user_abc123"
With orphan cleanup enabled:
curl "https://<your-prism-domain>/api/analytics/vector-graph?userId=user_abc123&cleanup=true"

Build docs developers (and LLMs) love