> ## 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.

# Auto-Generate Client Knowledge Boards

> Onboard new clients with AI-generated industry overviews, stakeholder maps, and action items. 10 minutes.

## What you'll build

An automated client onboarding workflow that creates a structured knowledge board from a client's public web presence and industry data.

* Board pre-populated with client website and industry reports
* AI-generated industry overview, stakeholder analysis, and key challenges
* Structured zones with action-item sticky notes
* Ready to share with the consulting or agency team

## Prerequisites

* ChatGrid API key ([get one here](/authentication))
* Node.js 18+ or Python 3.10+

## Step 1: Create a client board

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.chatgrid.ai/v1/boards \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{"name": "Client: Meridian Health Systems - Onboarding"}'
  ```

  ```typescript Node.js theme={null}
  const board = await fetch("https://api.chatgrid.ai/v1/boards", {
    method: "POST",
    headers: { Authorization: `Bearer ${API_KEY}`, "Content-Type": "application/json" },
    body: JSON.stringify({ name: "Client: Meridian Health Systems - Onboarding" }),
  }).then((r) => r.json());
  const boardId = board.data.id;
  ```

  ```python Python theme={null}
  import requests
  board = requests.post("https://api.chatgrid.ai/v1/boards",
      headers={"Authorization": f"Bearer {API_KEY}"},
      json={"name": "Client: Meridian Health Systems - Onboarding"}).json()
  board_id = board["data"]["id"]
  ```
</CodeGroup>

## Step 2: Add client website and industry report

Batch-add the client's public pages and a relevant industry report as source nodes.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.chatgrid.ai/v1/boards/{boardId}/nodes/batch \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "operations": [
        {"action": "create", "data": {"type": "url", "position": {"x": 0, "y": 0}, "data": {"url": "https://meridianhealth.com/about"}}},
        {"action": "create", "data": {"type": "url", "position": {"x": 420, "y": 0}, "data": {"url": "https://meridianhealth.com/leadership"}}},
        {"action": "create", "data": {"type": "url", "position": {"x": 840, "y": 0}, "data": {"url": "https://deloitte.com/insights/healthcare-outlook-2026"}}}
      ]
    }'
  ```

  ```typescript Node.js theme={null}
  const clientSources = [
    { type: "url", position: { x: 0, y: 0 }, data: { url: "https://meridianhealth.com/about" } },
    { type: "url", position: { x: 420, y: 0 }, data: { url: "https://meridianhealth.com/leadership" } },
    { type: "url", position: { x: 840, y: 0 }, data: { url: "https://deloitte.com/insights/healthcare-outlook-2026" } },
  ];
  await fetch(`https://api.chatgrid.ai/v1/boards/${boardId}/nodes/batch`, {
    method: "POST",
    headers: { Authorization: `Bearer ${API_KEY}`, "Content-Type": "application/json" },
    body: JSON.stringify({
      operations: clientSources.map((source) => ({ action: "create", data: source })),
    }),
  });
  ```

  ```python Python theme={null}
  client_sources = [
      {"type": "url", "position": {"x": 0, "y": 0}, "data": {"url": "https://meridianhealth.com/about"}},
      {"type": "url", "position": {"x": 420, "y": 0}, "data": {"url": "https://meridianhealth.com/leadership"}},
      {"type": "url", "position": {"x": 840, "y": 0}, "data": {"url": "https://deloitte.com/insights/healthcare-outlook-2026"}},
  ]
  requests.post(f"https://api.chatgrid.ai/v1/boards/{board_id}/nodes/batch",
      headers={"Authorization": f"Bearer {API_KEY}"},
      json={"operations": [{"action": "create", "data": source} for source in client_sources]})
  ```
</CodeGroup>

## Step 3: Vectorize all sources

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.chatgrid.ai/v1/boards/{boardId}/documents/vectorize \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "content": "Meridian Health Systems is expanding virtual care, modernizing patient intake, and consolidating analytics across regional clinics.",
      "metadata": {"source": "meridianhealth.com/about", "type": "client-research"}
    }'
  ```

  ```typescript Node.js theme={null}
  const sourceTexts = [
    {
      content: "Meridian Health Systems is expanding virtual care, modernizing patient intake, and consolidating analytics across regional clinics.",
      metadata: { source: "meridianhealth.com/about", type: "client-research" },
    },
    {
      content: "Leadership page notes: CTO owns data platform modernization; COO owns intake efficiency and care coordination.",
      metadata: { source: "meridianhealth.com/leadership", type: "stakeholders" },
    },
  ];
  await Promise.all(sourceTexts.map((source) =>
    fetch(`https://api.chatgrid.ai/v1/boards/${boardId}/documents/vectorize`, {
      method: "POST",
      headers: { Authorization: `Bearer ${API_KEY}`, "Content-Type": "application/json" },
      body: JSON.stringify(source),
    })
  ));
  ```

  ```python Python theme={null}
  import concurrent.futures
  source_texts = [
      {"content": "Meridian Health Systems is expanding virtual care, modernizing patient intake, and consolidating analytics across regional clinics.", "metadata": {"source": "meridianhealth.com/about", "type": "client-research"}},
      {"content": "Leadership page notes: CTO owns data platform modernization; COO owns intake efficiency and care coordination.", "metadata": {"source": "meridianhealth.com/leadership", "type": "stakeholders"}},
  ]
  def vectorize(source):
      return requests.post(f"https://api.chatgrid.ai/v1/boards/{board_id}/documents/vectorize",
          headers={"Authorization": f"Bearer {API_KEY}"}, json=source)
  with concurrent.futures.ThreadPoolExecutor(max_workers=3) as pool:
      list(pool.map(vectorize, source_texts))
  ```
</CodeGroup>

## Step 4: Generate AI analysis

Create a chat and ask AI for three deliverables: industry overview, stakeholder analysis, and key challenges.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.chatgrid.ai/v1/boards/{boardId}/chats \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{"title": "Onboarding Analysis"}'

  curl -X POST https://api.chatgrid.ai/v1/boards/{boardId}/chats/{chatId}/messages \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "content": "Based on the client materials and industry report on this board, generate:\n1. Industry Overview: trends, market dynamics, regulatory landscape\n2. Stakeholder Analysis: key executives and their likely priorities\n3. Key Challenges: top 5 challenges this client faces\nBe specific to this client, not generic.",
      "stream": false
    }'
  ```

  ```typescript Node.js theme={null}
  const chat = await fetch(`https://api.chatgrid.ai/v1/boards/${boardId}/chats`, {
    method: "POST",
    headers: { Authorization: `Bearer ${API_KEY}`, "Content-Type": "application/json" },
    body: JSON.stringify({ title: "Onboarding Analysis" }),
  }).then((r) => r.json());

  const report = await fetch(
    `https://api.chatgrid.ai/v1/boards/${boardId}/chats/${chat.data.id}/messages`,
    {
      method: "POST",
      headers: { Authorization: `Bearer ${API_KEY}`, "Content-Type": "application/json" },
      body: JSON.stringify({
        content: "Based on the client materials and industry report on this board, generate:\n1. Industry Overview: trends, market dynamics, regulatory landscape\n2. Stakeholder Analysis: key executives and their likely priorities\n3. Key Challenges: top 5 challenges this client faces\nBe specific to this client, not generic.",
        stream: false,
      }),
    }
  ).then((r) => r.json());
  ```

  ```python Python theme={null}
  chat = requests.post(f"https://api.chatgrid.ai/v1/boards/{board_id}/chats",
      headers={"Authorization": f"Bearer {API_KEY}"},
      json={"title": "Onboarding Analysis"}).json()

  report = requests.post(
      f"https://api.chatgrid.ai/v1/boards/{board_id}/chats/{chat['data']['id']}/messages",
      headers={"Authorization": f"Bearer {API_KEY}"},
      json={"content": "Based on the client materials and industry report on this board, generate:\n1. Industry Overview: trends, market dynamics, regulatory landscape\n2. Stakeholder Analysis: key executives and their likely priorities\n3. Key Challenges: top 5 challenges this client faces\nBe specific to this client, not generic.", "stream": False},
  ).json()
  ```
</CodeGroup>

## Step 5: Create structured zones with batch nodes

Organize the board into clear zones: one notepad per section, plus action-item sticky notes.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.chatgrid.ai/v1/boards/{boardId}/nodes/batch \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "operations": [
        {"action": "create", "data": {"type": "document", "position": {"x": 0, "y": 420}, "data": {"content": "# Industry Overview\n\n[Paste section 1 from AI output]"}}},
        {"action": "create", "data": {"type": "document", "position": {"x": 420, "y": 420}, "data": {"content": "# Stakeholder Analysis\n\n[Paste section 2 from AI output]"}}},
        {"action": "create", "data": {"type": "document", "position": {"x": 840, "y": 420}, "data": {"content": "# Key Challenges\n\n[Paste section 3 from AI output]"}}},
        {"action": "create", "data": {"type": "note", "position": {"x": 0, "y": 760}, "data": {"text": "ACTION: Schedule discovery call with CTO to validate tech priorities"}}},
        {"action": "create", "data": {"type": "note", "position": {"x": 420, "y": 760}, "data": {"text": "ACTION: Request org chart from client contact"}}},
        {"action": "create", "data": {"type": "note", "position": {"x": 840, "y": 760}, "data": {"text": "ACTION: Prepare pitch deck addressing top 3 challenges"}}}
      ]
    }'
  ```

  ```typescript Node.js theme={null}
  const sections = report.data.content.split(/(?=# )/).filter(Boolean);
  const zoneNodes = [
    { type: "document", position: { x: 0, y: 420 }, data: { content: sections[0] || "# Industry Overview\n\n[Pending]" } },
    { type: "document", position: { x: 420, y: 420 }, data: { content: sections[1] || "# Stakeholder Analysis\n\n[Pending]" } },
    { type: "document", position: { x: 840, y: 420 }, data: { content: sections[2] || "# Key Challenges\n\n[Pending]" } },
    { type: "note", position: { x: 0, y: 760 }, data: { text: "ACTION: Schedule discovery call with CTO" } },
    { type: "note", position: { x: 420, y: 760 }, data: { text: "ACTION: Request org chart from client contact" } },
    { type: "note", position: { x: 840, y: 760 }, data: { text: "ACTION: Prepare pitch deck addressing top 3 challenges" } },
  ];
  await fetch(`https://api.chatgrid.ai/v1/boards/${boardId}/nodes/batch`, {
    method: "POST",
    headers: { Authorization: `Bearer ${API_KEY}`, "Content-Type": "application/json" },
    body: JSON.stringify({
      operations: zoneNodes.map((node) => ({ action: "create", data: node })),
    }),
  });
  ```

  ```python Python theme={null}
  sections = [s for s in report["data"]["content"].split("# ") if s.strip()]
  zone_nodes = [
      {"type": "document", "position": {"x": 0, "y": 420}, "data": {"content": f"# {sections[0]}" if len(sections) > 0 else "# Industry Overview\n\n[Pending]"}},
      {"type": "document", "position": {"x": 420, "y": 420}, "data": {"content": f"# {sections[1]}" if len(sections) > 1 else "# Stakeholder Analysis\n\n[Pending]"}},
      {"type": "document", "position": {"x": 840, "y": 420}, "data": {"content": f"# {sections[2]}" if len(sections) > 2 else "# Key Challenges\n\n[Pending]"}},
      {"type": "note", "position": {"x": 0, "y": 760}, "data": {"text": "ACTION: Schedule discovery call with CTO"}},
      {"type": "note", "position": {"x": 420, "y": 760}, "data": {"text": "ACTION: Request org chart from client contact"}},
      {"type": "note", "position": {"x": 840, "y": 760}, "data": {"text": "ACTION: Prepare pitch deck addressing top 3 challenges"}},
  ]
  requests.post(f"https://api.chatgrid.ai/v1/boards/{board_id}/nodes/batch",
      headers={"Authorization": f"Bearer {API_KEY}"},
      json={"operations": [{"action": "create", "data": node} for node in zone_nodes]})
  ```
</CodeGroup>

## What's happening under the hood

The API stores source nodes on the board and vectorizes the text you provide. When the AI generates the analysis, it searches across vectorized content to find relevant passages from the client research and industry notes, producing a response grounded in source material rather than generic knowledge. The batch node endpoint applies all zone-node operations in one request.

## Next steps

<CardGroup cols={2}>
  <Card title="Research Pipeline" icon="magnifying-glass" href="/cookbooks/research-pipeline">
    Go deeper with multi-source research synthesis
  </Card>

  <Card title="Team Knowledge" icon="users" href="/cookbooks/team-knowledge">
    Share the onboarding board with your whole team
  </Card>
</CardGroup>
