Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.chatgrid.ai/llms.txt

Use this file to discover all available pages before exploring further.

What you’ll build

A research synthesis board that ingests multiple documents, finds cross-cutting themes, and creates a visual map linking findings to source material.
  • Upload and vectorize 5+ PDFs
  • Ask AI to identify themes across all sources
  • Create finding nodes connected to source documents
  • Search for specific topics across your entire document set

Prerequisites

  • ChatGrid API key (get one here)
  • Node.js 18+ or Python 3.10+
  • PDF files or document URLs to analyze

Step 1: Create a research board

curl -X POST https://api.chatgrid.ai/v1/boards \
  -H "Authorization: Bearer cgk_live_..." \
  -H "Content-Type: application/json" \
  -d '{"name": "Q1 Market Research Synthesis"}'

Step 2: Upload PDFs and create document nodes

Upload each PDF as an asset, then create a node on the canvas.
cURL
# Upload the file
curl -X POST https://api.chatgrid.ai/v1/boards/{boardId}/assets \
  -H "Authorization: Bearer cgk_live_..." \
  -F "file=@gartner-report-2026.pdf"

# Create a PDF node (use the asset URL from the upload response)
curl -X POST https://api.chatgrid.ai/v1/boards/{boardId}/nodes \
  -H "Authorization: Bearer cgk_live_..." \
  -H "Content-Type: application/json" \
  -d '{"type": "pdf", "position": {"x": 0, "y": 0}, "data": {"label": "Gartner Report 2026", "url": "{assetUrl}"}}'
Repeat for all documents. Here is how to batch it in Python:
Python
documents = [
    {"file": "gartner-report-2026.pdf", "label": "Gartner Report", "x": 0},
    {"file": "forrester-wave-q1.pdf", "label": "Forrester Wave Q1", "x": 400},
    {"file": "internal-survey.pdf", "label": "Customer Survey", "x": 800},
    {"file": "competitor-teardown.pdf", "label": "Competitor Teardown", "x": 0, "y": 350},
    {"file": "win-loss-analysis.pdf", "label": "Win/Loss Analysis", "x": 400, "y": 350},
]
node_ids = []
for doc in documents:
    with open(doc["file"], "rb") as f:
        upload = requests.post(f"{BASE}/boards/{board_id}/assets",
            headers={"Authorization": f"Bearer {API_KEY}"}, files={"file": f})
    asset_url = upload.json()["data"]["url"]
    node = requests.post(f"{BASE}/boards/{board_id}/nodes", headers=headers, json={
        "type": "pdf", "position": {"x": doc["x"], "y": doc.get("y", 0)},
        "data": {"label": doc["label"], "url": asset_url},
    })
    node_ids.append({"id": node.json()["data"]["id"], "label": doc["label"]})

Step 3: Vectorize all documents

Vectorize each document’s content, linking chunks to the source node.
curl -X POST https://api.chatgrid.ai/v1/boards/{boardId}/documents/vectorize \
  -H "Authorization: Bearer cgk_live_..." \
  -H "Content-Type: application/json" \
  -d '{"url": "{assetUrl}", "node_id": "{nodeId}", "metadata": {"source": "gartner-report-2026.pdf"}}'
# Repeat for each document
Large PDFs (50+ pages) may take 30-60 seconds. ChatGrid extracts text from scanned pages via OCR automatically.

Step 4: Ask AI to find themes

Create a chat and ask the AI to synthesize across all documents.
curl -X POST https://api.chatgrid.ai/v1/boards/{boardId}/chats \
  -H "Authorization: Bearer cgk_live_..." \
  -H "Content-Type: application/json" \
  -d '{"title": "Cross-Document Synthesis"}'

curl -X POST https://api.chatgrid.ai/v1/boards/{boardId}/chats/{chatId}/messages \
  -H "Authorization: Bearer cgk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "content": "Analyze all documents on this board. Identify the top 5 recurring themes. For each theme, cite which documents mention it and summarize the key points.",
    "stream": false
  }'

Step 5: Create finding nodes and connect to sources

Turn each theme into a sticky note and draw edges to the documents it references.
Python
themes = [
    {"label": "AI adoption accelerating", "content": "3 of 5 reports cite >40% YoY growth in AI tool adoption.", "sources": [node_ids[0], node_ids[1]], "x": 200},
    {"label": "Buyer consolidation", "content": "Teams reducing vendor count from 8 to 3.", "sources": [node_ids[1], node_ids[4]], "x": 600},
    {"label": "Self-serve preferred", "content": "72% prefer self-serve onboarding.", "sources": [node_ids[2], node_ids[4]], "x": 1000},
]
for theme in themes:
    node = requests.post(f"{BASE}/boards/{board_id}/nodes", headers=headers, json={
        "type": "sticky_note", "position": {"x": theme["x"], "y": 700},
        "data": {"label": f"Theme: {theme['label']}", "content": theme["content"]},
    })
    finding_id = node.json()["data"]["id"]
    for source in theme["sources"]:
        requests.post(f"{BASE}/boards/{board_id}/edges", headers=headers, json={
            "source_node_id": finding_id, "target_node_id": source["id"], "data": {"label": "cited in"},
        })

Step 6: Search for specific topics

Query across all documents without re-reading them.
cURL
curl -X POST https://api.chatgrid.ai/v1/boards/{boardId}/documents/search \
  -H "Authorization: Bearer cgk_live_..." \
  -H "Content-Type: application/json" \
  -d '{"query": "what do analysts say about pricing pressure in 2026?", "limit": 5}'
Results include matching text, similarity score, and source metadata so you can trace every finding back to its document.

What’s happening under the hood

Each uploaded PDF goes through text extraction (with OCR for scanned pages), chunking into ~500-token segments with overlap, and embedding via pgvector. The node_id parameter ties chunks to their visual node, so edges between finding nodes and source nodes are meaningful. When AI answers a synthesis question, it performs semantic search across all chunks on the board and reasons over the top matches. The metadata you attach appears in search results, making claims easy to verify.

Next steps

Meeting Knowledge

Turn meeting notes into searchable knowledge

Competitive Intel

Track competitor websites and compare positioning