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

# Meibel

> Parse, transform, ingest, and put agents on your data. Powerful primitives, one API.

<div className="max-w-5xl mx-auto px-6 pt-36 lg:pt-16 pb-12">
  <div className="not-prose text-center pb-12">
    <p className="text-xs font-mono uppercase tracking-widest text-primary dark:text-primary-light mb-4">Meibel documentation</p>

    <h1 className="font-normal tracking-tight leading-[1.05] text-zinc-900 dark:text-white" style={{fontSize: "clamp(1.5rem, 6vw, 3.75rem)"}}>
      Powerful primitives. <br className="sm:hidden" />One API. <br />Deeply integrated.
    </h1>

    <p className="mt-5 text-lg text-zinc-600 dark:text-zinc-400 max-w-2xl mx-auto">
      Parse documents, transform their content into your schema, ingest it into a queryable datasource, and put agents on top. Each through a single API, with no vector store to run, no graph database to wire up, and no separate orchestration layer to maintain.
    </p>

    <div className="mt-7 flex gap-3 justify-center flex-wrap">
      <a href="/installation" className="inline-flex items-center px-5 py-2.5 rounded-lg bg-primary text-white font-medium hover:bg-primary-dark transition-colors no-underline">Get started</a>
      <a href="/api-reference/introduction" className="inline-flex items-center px-5 py-2.5 rounded-lg border border-zinc-200 dark:border-zinc-800 font-medium hover:bg-zinc-50 dark:hover:bg-zinc-900 transition-colors no-underline">API reference</a>
    </div>
  </div>

  <div className="not-prose mt-4 mb-6">
    <div className="text-xs font-medium uppercase tracking-[0.18em] text-[#1A3D96] dark:text-blue-300 mb-3 font-mono">Where to go next</div>
    <h2 className="text-3xl font-medium tracking-tight text-zinc-900 dark:text-white">Browse the docs</h2>
    <p className="mt-2 text-base text-zinc-600 dark:text-zinc-400">Jump into any section of the documentation.</p>
  </div>

  <CardGroup cols={3}>
    <Card title="Get started" icon="rocket" href="/installation">
      Install the SDK, set your API key, and make your first call.
    </Card>

    <Card title="Core concepts" icon="cube" href="/concepts/agents">
      Agents, datasources, batches, execution policies, and confidence scoring.
    </Card>

    <Card title="Guides" icon="book-open" href="/guides/agents">
      Task-first walkthroughs for agents, sessions, data, and documents.
    </Card>

    <Card title="API reference" icon="code" href="/api-reference/introduction">
      Every endpoint, parameter, and response, with a live playground.
    </Card>

    <Card title="SDKs" icon="terminal" href="/sdk/python">
      Python, TypeScript, Go, and CLI. One client covers every primitive.
    </Card>

    <Card title="Tutorials" icon="graduation-cap" href="/tutorials/datasource-csv-tutorial">
      End-to-end examples like asking a million-row CSV precise questions.
    </Card>
  </CardGroup>

  <div className="not-prose mt-16 mb-6">
    <div className="text-xs font-medium uppercase tracking-[0.18em] text-[#1A3D96] dark:text-blue-300 mb-3 font-mono">The pipeline in code</div>
    <h2 className="text-3xl font-medium tracking-tight text-zinc-900 dark:text-white">From data to agent</h2>
    <p className="mt-2 text-base text-zinc-600 dark:text-zinc-400">One pipeline, four stages: parse a document, transform to your schema, ingest into a datasource, put an agent on top.</p>
  </div>

  <Tabs>
    <Tab title="1. Parse">
      ```python parse.py theme={null}
      import os
      from meibel import MeibelClient

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

      # Parse any document into structured content, with
      # hierarchy, tables, and visual elements preserved.
      with open("rfq.pdf", "rb") as f:
          parsed = client.documents.process(file=f, file_name="rfq.pdf")

      print(parsed.result)
      ```
    </Tab>

    <Tab title="2. Transform">
      ```python transform.py theme={null}
      # Reshape document content into your schema,
      # with per-field confidence scores. Reference a
      # schema by name, or pass a dict or Pydantic model.
      extracted = client.documents.transform(
          file="rfq.pdf",
          schema="quote_v3",
      )

      print(extracted.data)
      ```
    </Tab>

    <Tab title="3. Ingest">
      ```python ingest.py theme={null}
      from meibel.models import MoveDocumentsRequest

      # Move the parsed document straight into a new datasource,
      # by job ID. No re-upload, no vector store to manage.
      moved = client.documents.move(
          body=MoveDocumentsRequest(
              documents=[parsed.job_id],
              new_datasource_name="rfqs",
          )
      )

      client.datasources.ingest.trigger(datasource_id=moved.datasource_id)
      ```
    </Tab>

    <Tab title="4. Agent">
      ```python agent.py theme={null}
      from meibel.models import (
          CreateAgentDefinitionRequest,
          ChatMessageRequest,
      )

      # An agent binds to one or more datasources, holding
      # unstructured documents, structured tables, or both.
      agent = client.agents.create(
          body=CreateAgentDefinitionRequest(
              display_name="Quote reviewer",
              instructions="Answer using only the ingested RFQs.",
              datasources=[moved.datasource_id],
          )
      )

      # Open a session, then chat.
      session = client.agents.sessions.create(agent_id=agent.id)

      reply = client.agents.sessions.send_chat_message(
          session_id=session.session_id,
          body=ChatMessageRequest(user_message="Draft a response to this RFQ."),
      )
      print(reply.assistant_response)
      ```
    </Tab>
  </Tabs>

  <div className="not-prose mt-16 mb-6">
    <div className="text-xs font-medium uppercase tracking-[0.18em] text-[#1A3D96] dark:text-blue-300 mb-3 font-mono">Building blocks</div>
    <h2 className="text-3xl font-medium tracking-tight text-zinc-900 dark:text-white">Powerful primitives</h2>
    <p className="mt-2 text-base text-zinc-600 dark:text-zinc-400">Each through a single API. Use one, or compose them into a full pipeline.</p>
  </div>

  <CardGroup cols={2}>
    <Card title="01 · Parsing" icon="file-lines" href="/guides/documents">
      Turn PDFs, spreadsheets, and images into typed content, with hierarchy, tables, and visual elements preserved.
    </Card>

    <Card title="02 · Transform" icon="wand-magic-sparkles" href="/guides/deep-transform">
      Reshape any source into your schema with per-field confidence scores.
    </Card>

    <Card title="03 · Datasources" icon="database" href="/guides/datasources">
      A living, queryable store for structured and unstructured data, with no vector database to manage.
    </Card>

    <Card title="04 · Agents" icon="robot" href="/guides/agents">
      Reasoning that knows your data and your rules, scoped by execution policies and run one-off or in batches.
    </Card>
  </CardGroup>

  <div className="not-prose mt-16 mb-6">
    <div className="text-xs font-medium uppercase tracking-[0.18em] text-[#1A3D96] dark:text-blue-300 mb-3 font-mono">How the stack composes</div>
    <h2 className="text-3xl font-medium tracking-tight text-zinc-900 dark:text-white">Deeply integrated.</h2>
    <p className="mt-3 text-base text-zinc-600 dark:text-zinc-400 max-w-[70ch]">The primitives aren't just co-located. Each one folds its output into the next, so quality compounds down the pipeline instead of degrading. What parsing captures, transform reshapes; what transform yields, ingestion indexes; what ingestion structures, agents reason over; and policy and confidence thread through all of it.</p>
  </div>

  <div className="relative pl-12 mt-8">
    <div className="absolute top-3 bottom-3 z-0" style={{left: "18px", width: "6px", background: "#1A3D96"}} />

    <div className="absolute z-10" style={{left: "21px", top: "12px", transform: "translate(-50%, -100%)", width: 0, height: 0, borderLeft: "9px solid transparent", borderRight: "9px solid transparent", borderBottom: "12px solid #1A3D96"}} />

    <div className="absolute z-10" style={{left: "21px", bottom: "12px", transform: "translate(-50%, 50%)", width: "14px", height: "14px", borderRadius: "9999px", background: "#1A3D96"}} />

    <div className="relative z-10 bg-white dark:bg-zinc-900 border border-zinc-200 dark:border-zinc-800 rounded-2xl px-6 py-5 mb-3">
      <div className="flex items-start gap-4">
        <span className="font-mono text-xs font-semibold text-[#1A3D96] bg-[#E5EBF7] dark:bg-[#0F2560]/40 dark:text-blue-300 rounded-md px-2 py-1.5 min-w-[34px] text-center leading-none">04</span>

        <div className="flex-1 min-w-0">
          <div className="flex items-center gap-3 flex-wrap">
            <span className="text-lg font-medium tracking-tight text-zinc-900 dark:text-white">Agents</span>
            <span className="font-mono text-[10px] font-medium text-zinc-400 dark:text-zinc-500 tracking-[0.12em]">REASONING</span>
          </div>

          <p className="text-sm text-zinc-600 dark:text-zinc-400 mt-1.5 leading-relaxed max-w-[60ch]">Reason over structured and unstructured data, on retrieval sharpened by everything below. The cleaner the layers below, the sharper the answers.</p>
        </div>
      </div>
    </div>

    <div className="relative z-10 bg-white dark:bg-zinc-900 border border-zinc-200 dark:border-zinc-800 rounded-2xl px-6 py-5 mb-3">
      <div className="flex items-start gap-4">
        <span className="font-mono text-xs font-semibold text-[#1A3D96] bg-[#E5EBF7] dark:bg-[#0F2560]/40 dark:text-blue-300 rounded-md px-2 py-1.5 min-w-[34px] text-center leading-none">03</span>

        <div className="flex-1 min-w-0">
          <div className="flex items-center gap-3 flex-wrap">
            <span className="text-lg font-medium tracking-tight text-zinc-900 dark:text-white">Ingest</span>
            <span className="font-mono text-[10px] font-medium text-zinc-400 dark:text-zinc-500 tracking-[0.12em]">INDEX</span>
          </div>

          <p className="text-sm text-zinc-600 dark:text-zinc-400 mt-1.5 leading-relaxed max-w-[60ch]">Runs two paths at once: structured data lands in typed, queryable tables, while unstructured content is chunked along semantic boundaries into dense and sparse embeddings for hybrid retrieval. Both live in one datasource, with no vector store to manage.</p>
        </div>
      </div>
    </div>

    <div className="relative z-10 bg-white dark:bg-zinc-900 border border-zinc-200 dark:border-zinc-800 rounded-2xl px-6 py-5 mb-3">
      <div className="flex items-start gap-4">
        <span className="font-mono text-xs font-semibold text-[#1A3D96] bg-[#E5EBF7] dark:bg-[#0F2560]/40 dark:text-blue-300 rounded-md px-2 py-1.5 min-w-[34px] text-center leading-none">02</span>

        <div className="flex-1 min-w-0">
          <div className="flex items-center gap-3 flex-wrap">
            <span className="text-lg font-medium tracking-tight text-zinc-900 dark:text-white">Transform</span>
            <span className="font-mono text-[10px] font-medium text-zinc-400 dark:text-zinc-500 tracking-[0.12em]">SCHEMA</span>
          </div>

          <p className="text-sm text-zinc-600 dark:text-zinc-400 mt-1.5 leading-relaxed max-w-[60ch]">Reshapes parsed content into your business schema, with per-field confidence. The structured fields it yields fold into ingestion and sharpen what agents retrieve.</p>
        </div>
      </div>
    </div>

    <div className="relative z-10 bg-white dark:bg-zinc-900 border border-zinc-200 dark:border-zinc-800 rounded-2xl px-6 py-5">
      <div className="flex items-start gap-4">
        <span className="font-mono text-xs font-semibold text-[#1A3D96] bg-[#E5EBF7] dark:bg-[#0F2560]/40 dark:text-blue-300 rounded-md px-2 py-1.5 min-w-[34px] text-center leading-none">01</span>

        <div className="flex-1 min-w-0">
          <div className="flex items-center gap-3 flex-wrap">
            <span className="text-lg font-medium tracking-tight text-zinc-900 dark:text-white">Parse</span>
            <span className="font-mono text-[10px] font-medium text-[#1A3D96] dark:text-blue-300 tracking-[0.12em]">FOUNDATION</span>
          </div>

          <p className="text-sm text-zinc-600 dark:text-zinc-400 mt-1.5 leading-relaxed max-w-[60ch]">Captures deep structure (sections, headings, tables, lists) plus context for charts, graphs and formulas. Every extracted token carries a confidence score. Everything above inherits this structure.</p>
        </div>
      </div>
    </div>
  </div>

  <div className="flex justify-end pl-12 mt-4">
    <span className="font-mono text-[11px] text-[#1A3D96] dark:text-blue-300 tracking-wide flex items-center gap-2">
      <span className="inline-block w-0 h-0 border-l-[5px] border-l-transparent border-r-[5px] border-r-transparent border-b-[8px] border-b-[#1A3D96] dark:border-b-blue-300" />

      structure & quality compound upward
    </span>
  </div>

  <div className="not-prose mt-16 mb-6">
    <div className="text-xs font-medium uppercase tracking-[0.18em] text-[#1A3D96] dark:text-blue-300 mb-3 font-mono">Enforced by the platform</div>
    <h2 className="text-3xl font-medium tracking-tight text-zinc-900 dark:text-white">Hardrails, not guardrails</h2>
    <p className="mt-2 text-base text-zinc-600 dark:text-zinc-400">Lock agents to the data and tools you trust, enforced in code, not vibes. Execution policies strictly define what an agent can see and do. They're evaluated by the platform, outside the LLM, so the model can't bypass them through prompting.</p>
    <p className="mt-3 text-base text-zinc-600 dark:text-zinc-400">The result: agents that stay in-bounds by construction, not persuasion.</p>
  </div>

  <Tabs>
    <Tab title="Unstructured data">
      ```json policy.json theme={null}
      {
        "datasources": {
          "ds_abc123": {
            "documents": {
              "filter": {
                "data_element.__id__": { "$in": ["de_abc", "de_def"] }
              }
            }
          }
        }
      }
      ```
    </Tab>

    <Tab title="Structured data">
      ```json policy.json theme={null}
      {
        "datasources": {
          "ds_abc123": {
            "tables": {
              "filter": {
                "table.__name__": { "$in": ["orders", "customers"] },
                "orders.region": "EU"
              },
              "hidden_columns": {
                "customers": ["ssn", "credit_card"]
              }
            }
          }
        }
      }
      ```
    </Tab>

    <Tab title="Tools">
      ```json policy.json theme={null}
      {
        "tools": {
          "send_email": {
            "variables": {
              "to": "support@acme.com",
              "max_attachments": { "$lte": 3 }
            }
          },
          "web_search": { "disabled": true }
        }
      }
      ```
    </Tab>
  </Tabs>

  <div className="mt-6">
    <CardGroup cols={3}>
      <Card title="Before the LLM call" icon="filter">Disabled tools and off-limits tables are stripped out of the schemas the agent sees. Constraints show up directly in parameter descriptions.</Card>
      <Card title="During data access" icon="database">Table filters are pushed down into SQL and document filters into vector search. The agent never even sees rows or documents that don't match.</Card>
      <Card title="At tool execution" icon="stamp">Every tool call is validated against the policy before it runs. Non-compliant calls are blocked: no side effects, no exceptions.</Card>
    </CardGroup>
  </div>

  <div className="not-prose mt-16 mb-6">
    <div className="text-xs font-medium uppercase tracking-[0.18em] text-[#1A3D96] dark:text-blue-300 mb-3 font-mono">Get started</div>
    <h2 className="text-3xl font-medium tracking-tight text-zinc-900 dark:text-white">Connected in under a minute</h2>
    <p className="mt-2 text-base text-zinc-600 dark:text-zinc-400">Install the SDK, verify your key, and make your first call.</p>
  </div>

  <Steps>
    <Step title="Install the SDK">
      ```bash theme={null}
      pip install meibel
      ```
    </Step>

    <Step title="Verify your key">
      ```python verify.py theme={null}
      import os
      from meibel import MeibelClient

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

      result = client.datasources.list()
      print(f"Connected: {len(result.datasources)} datasource(s) found")
      ```
    </Step>

    <Step title="Make your first call">
      Head to the [quickstart](/quickstart) for a full walkthrough.
    </Step>
  </Steps>
</div>
