> ## Documentation Index
> Fetch the complete documentation index at: https://docs.meibel.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Quick Start

> Build your first AI-powered workflow with Meibel

This guide walks you through the three pillars of Meibel -- **Context**, **Agents**, and **Confidence** -- in a single end-to-end workflow. By the end, you will have parsed a document, built a knowledge base, created an agent, and chatted with it.

<Note>
  Before you begin, make sure you have [installed an SDK and set your API key](/installation).
</Note>

## Step 1: Parse a Document

Start with the **Context** pillar. Meibel can parse any document (PDF, DOCX, images) and return structured content in a single synchronous call.

<CodeGroup>
  ```python Python theme={null}
  import os
  from meibel import MeibelClient

  client = MeibelClient(api_key=os.environ["MEIBEL_API_KEY"])

  with open("document.pdf", "rb") as f:
      result = client.documents.process_document(file=f, file_name="document.pdf")

  print(result.content)
  ```

  ```typescript TypeScript theme={null}
  import { MeibelClient } from "meibel";
  import { readFile } from "node:fs/promises";

  const client = new MeibelClient({
    apiKey: process.env.MEIBEL_API_KEY,
  });

  const result = await client.documents.processDocument(
    new Blob([await readFile("document.pdf")]),
    "document.pdf",
  );
  console.log(result.content);
  ```

  ```go Go theme={null}
  package main

  import (
      "context"
      "fmt"
      "os"

      meibel "github.com/meibel-ai/meibel-go"
  )

  func main() {
      client := meibel.NewClient(
          meibel.WithAPIKey(os.Getenv("MEIBEL_API_KEY")),
      )

      file, _ := os.Open("document.pdf")
      defer file.Close()

      result, err := client.Documents.ProcessDocument(
          context.Background(), file, "document.pdf", nil,
      )
      if err != nil {
          panic(err)
      }
      fmt.Println(result.Content)
  }
  ```

  ```bash CLI theme={null}
  meibel documents parse --file document.pdf --wait
  ```
</CodeGroup>

`process_document` handles parsing, OCR, and structuring in one step. The response contains the extracted text, tables, and metadata.

## Step 2: Create a Datasource and Upload Content

Documents become searchable once they live inside a **datasource** -- a managed knowledge base that agents can query.

<CodeGroup>
  ```python Python theme={null}
  from meibel.models import CreateDatasourceRequest, ConnectorConfig

  # Create a datasource
  datasource = client.datasources.create_datasource(
      body=CreateDatasourceRequest(
          name="Product Knowledge Base",
          description="Internal product documentation and reports",
          connector=ConnectorConfig(type="managed"),
      )
  )
  ds_id = datasource.id
  print(f"Created datasource: {ds_id}")

  # Upload a file into it
  with open("report.pdf", "rb") as f:
      client.content.upload_content(file=f, file_name="report.pdf")

  # Trigger ingestion so the content becomes searchable
  client.content.trigger_ingest(datasource_id=ds_id)
  print("Ingestion started")
  ```

  ```typescript TypeScript theme={null}
  import { readFile } from "node:fs/promises";

  // Create a datasource
  const datasource = await client.datasources.createDatasource({
    name: "Product Knowledge Base",
    description: "Internal product documentation and reports",
    connector: { type: "managed" },
  });
  const dsId = datasource.id;
  console.log(`Created datasource: ${dsId}`);

  // Upload a file into it
  const fileBlob = new Blob([await readFile("report.pdf")]);
  await client.fileUpload.uploadContent(fileBlob, "report.pdf", {
    datasourceId: dsId,
  });

  // Trigger ingestion so the content becomes searchable
  await client.ingest.triggerIngest(dsId);
  console.log("Ingestion started");
  ```

  ```go Go theme={null}
  ds, err := client.Datasources.CreateDatasource(context.Background(), meibel.CreateDatasourceRequest{
      Name:        "Product Knowledge Base",
      Description: "Internal product documentation and reports",
      Connector:   meibel.ConnectorConfig{Type: "managed"},
  })
  if err != nil {
      panic(err)
  }
  fmt.Printf("Created datasource: %s\n", ds.ID)

  file, _ := os.Open("report.pdf")
  defer file.Close()

  _, err = client.Content.UploadContent(context.Background(), file, "report.pdf")
  if err != nil {
      panic(err)
  }

  _, err = client.Content.TriggerIngest(context.Background(), ds.ID)
  if err != nil {
      panic(err)
  }
  fmt.Println("Ingestion started")
  ```

  ```bash CLI theme={null}
  # Create a datasource
  meibel datasources create \
    --data '{"name":"Product Knowledge Base","description":"Internal product documentation and reports","connector":{"type":"managed"}}'

  # Upload content
  meibel content upload --file report.pdf

  # Trigger ingestion (use the datasource ID from the create output)
  meibel content trigger-ingest <datasource-id>
  ```
</CodeGroup>

Ingestion runs asynchronously. Once complete, the content is indexed and available for agent queries.

## Step 3: Create an Agent

Now move to the **Agentic** pillar. An agent combines a system prompt with one or more datasources to answer questions grounded in your content.

<CodeGroup>
  ```python Python theme={null}
  from meibel.models import CreateAgentDefinitionRequest, PublishAgentDefinitionRequest

  # Create the agent
  agent = client.agents.create_agent(
      body=CreateAgentDefinitionRequest(
          display_name="Product Assistant",
          description="Answers questions about product documentation",
          instructions="You are a helpful product assistant. Answer questions using only the provided knowledge base. If you don't know the answer, say so.",
      )
  )
  agent_id = agent.id
  print(f"Created agent: {agent_id}")

  # Publish it so it can accept chat sessions
  client.agents.publish_agent(
      agent_id=agent_id,
      body=PublishAgentDefinitionRequest(commit_message="Initial release"),
  )
  print("Agent published")
  ```

  ```typescript TypeScript theme={null}
  // Create the agent
  const agent = await client.agents.createAgent({
    displayName: "Product Assistant",
    description: "Answers questions about product documentation",
    instructions:
      "You are a helpful product assistant. Answer questions using only the provided knowledge base. If you don't know the answer, say so.",
  });
  const agentId = agent.id;
  console.log(`Created agent: ${agentId}`);

  // Publish it so it can accept chat sessions
  await client.agents.publishAgent(agentId, {
    commitMessage: "Initial release",
  });
  console.log("Agent published");
  ```

  ```go Go theme={null}
  agent, err := client.Agents.CreateAgent(context.Background(), meibel.CreateAgentDefinitionRequest{
      DisplayName:  "Product Assistant",
      Description:  "Answers questions about product documentation",
      Instructions: "You are a helpful product assistant. Answer questions using only the provided knowledge base. If you don't know the answer, say so.",
  })
  if err != nil {
      panic(err)
  }
  fmt.Printf("Created agent: %s\n", agent.ID)

  _, err = client.Agents.PublishAgent(context.Background(), agent.ID, meibel.PublishAgentDefinitionRequest{
      CommitMessage: "Initial release",
  })
  if err != nil {
      panic(err)
  }
  fmt.Println("Agent published")
  ```

  ```bash CLI theme={null}
  # Create the agent
  meibel agents create \
    --data '{"display_name":"Product Assistant","description":"Answers questions about product documentation","instructions":"You are a helpful product assistant. Answer questions using only the provided knowledge base. If you don'\''t know the answer, say so."}'

  # Publish it (use the agent ID from the previous output)
  meibel agents publish <agent-id> \
    --data '{"commit_message":"Initial release"}'
  ```
</CodeGroup>

## Step 4: Chat with the Agent

Start a session and send a message. Each session maintains its own conversation history.

<CodeGroup>
  ```python Python theme={null}
  from meibel.models import ChatMessageRequest

  # Create a session
  session = client.agents.create_session(agent_id=agent_id)
  session_id = session.session_id
  print(f"Session: {session_id}")

  # Send a message
  response = client.sessions.send_chat_message(
      session_id=session_id,
      body=ChatMessageRequest(user_message="What does the product do?"),
  )
  print(response.message)
  ```

  ```typescript TypeScript theme={null}
  // Create a session
  const session = await client.agents.createSession(agentId);
  const sessionId = session.sessionId;
  console.log(`Session: ${sessionId}`);

  // Send a message
  const response = await client.sessions.sendChatMessage(sessionId, {
    userMessage: "What does the product do?",
  });
  console.log(response.message);
  ```

  ```go Go theme={null}
  session, err := client.Agents.CreateSession(context.Background(), agent.ID, nil)
  if err != nil {
      panic(err)
  }
  fmt.Printf("Session: %s\n", session.ID)

  response, err := client.Sessions.SendChatMessage(context.Background(), session.ID, meibel.ChatMessageRequest{
      UserMessage: "What does the product do?",
  })
  if err != nil {
      panic(err)
  }
  fmt.Println(response.Message)
  ```

  ```bash CLI theme={null}
  # Create a session
  meibel agents create-session <agent-id>

  # Send a message
  meibel sessions send-chat-message <session-id> \
    --data '{"user_message":"What does the product do?"}'
  ```
</CodeGroup>

## Step 5: Stream a Response

For a real-time experience, stream the agent's reply token-by-token. This is ideal for chat interfaces where you want to show output as it is generated.

<CodeGroup>
  ```python Python theme={null}
  stream = client.sessions.send_chat_message_stream(
      session_id=session_id,
      body=ChatMessageRequest(user_message="Summarize the key features"),
  )
  for event in stream:
      print(event.delta, end="", flush=True)
  print()  # newline after stream completes
  ```

  ```typescript TypeScript theme={null}
  // Note: streaming uses multipart encoding; check SDK docs for the latest signature
  const stream = await client.sessions.sendChatMessageStream(sessionId, {
    userMessage: "Summarize the key features",
  });
  for await (const event of stream) {
    process.stdout.write(event.delta);
  }
  console.log(); // newline after stream completes
  ```

  ```go Go theme={null}
  stream, err := client.Sessions.SendChatMessageStream(context.Background(), session.ID, meibel.ChatMessageRequest{
      UserMessage: "Summarize the key features",
  })
  if err != nil {
      panic(err)
  }
  for event := range stream.Events() {
      fmt.Print(event.Delta)
  }
  fmt.Println()
  ```

  ```bash CLI theme={null}
  meibel sessions send-chat-message-stream <session-id> \
    --data '{"user_message":"Summarize the key features"}'
  ```
</CodeGroup>

## Step 6: Check Confidence

The **Confidence** pillar is built into every response. When an agent answers a question, the response includes confidence metadata that tells you how well-grounded the answer is in your datasource content.

<CodeGroup>
  ```python Python theme={null}
  response = client.sessions.send_chat_message(
      session_id=session_id,
      body=ChatMessageRequest(user_message="What is the pricing model?"),
  )

  print(f"Answer: {response.message}")
  print(f"Confidence: {response.confidence.score}")
  print(f"Sources: {len(response.confidence.citations)} citation(s)")

  for citation in response.confidence.citations:
      print(f"  - {citation.source}: {citation.text[:80]}...")
  ```

  ```typescript TypeScript theme={null}
  const response = await client.sessions.sendChatMessage(sessionId, {
    userMessage: "What is the pricing model?",
  });

  console.log(`Answer: ${response.message}`);
  console.log(`Confidence: ${response.confidence.score}`);
  console.log(`Sources: ${response.confidence.citations.length} citation(s)`);

  for (const citation of response.confidence.citations) {
    console.log(`  - ${citation.source}: ${citation.text.slice(0, 80)}...`);
  }
  ```

  ```go Go theme={null}
  response, err := client.Sessions.SendChatMessage(context.Background(), session.ID, meibel.ChatMessageRequest{
      UserMessage: "What is the pricing model?",
  })
  if err != nil {
      panic(err)
  }

  fmt.Printf("Answer: %s\n", response.Message)
  fmt.Printf("Confidence: %v\n", response.Confidence.Score)
  fmt.Printf("Sources: %d citation(s)\n", len(response.Confidence.Citations))

  for _, c := range response.Confidence.Citations {
      text := c.Text
      if len(text) > 80 {
          text = text[:80] + "..."
      }
      fmt.Printf("  - %s: %s\n", c.Source, text)
  }
  ```

  ```bash CLI theme={null}
  # Confidence data is included in the default JSON output
  meibel sessions send-chat-message <session-id> \
    --data '{"user_message":"What is the pricing model?"}'
  ```
</CodeGroup>

Confidence scores let you build guardrails -- for example, flagging low-confidence answers for human review or requiring a minimum score before showing a response to end users.

## What's Next?

You have now used all three pillars of the Meibel platform. Dive deeper into each area:

<CardGroup cols={2}>
  <Card title="Context Engineering" icon="database" href="/concepts/context-engineering">
    Learn how datasources, documents, and ingestion work together
  </Card>

  <Card title="Agents" icon="robot" href="/concepts/agents">
    Understand agent definitions, publishing, and versioning
  </Card>

  <Card title="Confidence Scoring" icon="chart-line" href="/concepts/confidence-scoring">
    Deep dive into confidence metrics, citations, and thresholds
  </Card>

  <Card title="Streaming Guide" icon="bolt" href="/guides/streaming">
    SSE streaming patterns and best practices
  </Card>
</CardGroup>
