Documentation/Getting Started

Getting Started: Data → Knowledge Graph → Agent

This walkthrough covers the one path every new tenant actually needs end to end: connect a data source, get it into the Customer Knowledge Graph (CKG), create an agent, and run it. Every request below is a real, currently-implemented endpoint — copy/paste and adjust the IDs. For account creation and SDK installation, see Quick Start first.

All requests below need a bearer token. Login uses an OAuth2 form body (not JSON):

curl -X POST https://your-control-plane-host/api/v1/auth/login \
  -d "username=you@example.com&password=your-password"
# -> { "access_token": "...", "token_type": "bearer" }
export TOKEN="the-access_token-value-from-above"

Agent creation below also needs a tenant_id. Get it from your tenant memberships:

curl https://your-control-plane-host/api/v1/auth/me \
  -H "Authorization: Bearer $TOKEN"
# -> { "tenants": [{ "id": "<tenant_id>", "name": "...", "slug": "...", "tier": "..." }], ... }
export TENANT_ID="the-tenant-id-from-above"

Step 1 — Connect a data source

Connectors are created from the built-in catalog (Slack, GitHub, Jira, Confluence, and 70+ others — see IntegrationType in app/models/models.py). There is no generic "create a connector" endpoint; you materialize one from a catalog slug:

curl -X POST https://your-control-plane-host/api/v1/connectors/from-catalog \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"slug": "github"}'
# -> { "id": "<connector_id>", "status": "disconnected", ... }

Then authorize it. OAuth connectors return a redirect URL; non-OAuth connectors (API-key style) take a secrets object directly. In practice this step is done from the Connectors page in the dashboard, since OAuth connectors need a browser redirect back to /connectors/oauth/callback:

curl -X POST https://your-control-plane-host/api/v1/connectors/{connector_id}/authorize \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"secrets": {"api_token": "your-source-api-token"}}'

Once status is connected, discover what it can pull in, and pick what you want:

curl https://your-control-plane-host/api/v1/connectors/{connector_id}/resources \
  -H "Authorization: Bearer $TOKEN"
# -> { "resources": [{ "id": "org/repo", "name": "...", "type": "repo", ... }], "total": N }

Create a sync configuration, then trigger a sync run. sync_mode controls what happens next:

  • bulk_review — every fetched document is staged for your team to approve/reject before it goes anywhere (this is the default reviewed path).
  • selective — fetched documents skip staging and go straight to extraction. Use this only for sources you already trust.
curl -X POST https://your-control-plane-host/api/v1/connectors/{connector_id}/sync-config \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{
    "sync_mode": "bulk_review",
    "sync_frequency": "manual",
    "sync_scope": {"resource_ids": ["org/repo"]}
  }'

curl -X POST https://your-control-plane-host/api/v1/connectors/{connector_id}/sync \
  -H "Authorization: Bearer $TOKEN"
# -> { "id": "<sync_job_id>", "status": "running", "documents_fetched": 0, ... }

Step 2 — Review and approve into the Knowledge Graph

For bulk_review syncs, list what got staged and approve the documents you want ingested:

curl https://your-control-plane-host/api/v1/connectors/{connector_id}/sync-jobs/{sync_job_id}/staged \
  -H "Authorization: Bearer $TOKEN"

curl -X POST https://your-control-plane-host/api/v1/connectors/{connector_id}/sync-jobs/{sync_job_id}/staged/approve \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"document_ids": ["<staged_doc_id_1>", "<staged_doc_id_2>"]}'

Approving does three things automatically, in order: commits the approved documents into a Document Vault (auto-created per tenant on first sync — see Vault in the sidebar), runs the N-pass extraction pipeline against them, and writes the resulting entities/relationships as nodes and edges in the CKG. There's no separate "ingest" call to make for connector-synced documents — approval is the trigger.

Once extraction finishes, the nodes are queryable and visible in the Knowledge Graph page:

curl "https://your-control-plane-host/api/v1/ckg/nodes?kind=entity" \
  -H "Authorization: Bearer $TOKEN"

If you instead add documents to a vault directly (via Vault → Upload or POST /api/v1/vaults/{vault_id}/documents), those go through the vault's own Raw → Workspace → Canonical review flow, and extraction is triggered explicitly with POST /api/v1/vaults/{vault_id}/ingest. Connector syncs and manual vault uploads both end up in the same CKG — they just reach it via different trigger points.

Step 3 — Create an agent

Agents are control-plane records — name, model config, system prompt, memory settings. tenant_id is a query parameter, not part of the body:

curl -X POST "https://your-control-plane-host/api/v1/agents?tenant_id=$TENANT_ID" \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{
    "name": "Support Assistant",
    "description": "Answers account and billing questions",
    "agent_type": "custom",
    "config_schema": {
      "model": "claude-sonnet-4-6",
      "temperature": 0.7,
      "max_tokens": 4096,
      "system_prompt": "You are a friendly, concise customer support agent."
    }
  }'
# -> { "id": "<agent_id>", "status": "draft", ... }

Set config_schema.model explicitly to a real Claude model string. If you omit config_schema entirely, the default template ships "model": "gpt-4", which the chat endpoint below passes straight to the Anthropic SDK and will fail.

Agents are created in draft status. Activate before treating it as live:

curl -X POST https://your-control-plane-host/api/v1/agents/{agent_id}/activate \
  -H "Authorization: Bearer $TOKEN"

Step 4 — Run it

POST /agents/{agent_id}/chat calls Claude with the agent's stored system_prompt and model, using your conversation history for context:

curl -X POST https://your-control-plane-host/api/v1/agents/{agent_id}/chat \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{
    "message": "What data sources do we have connected?",
    "history": []
  }'
# -> { "response": "...", "model": "claude-sonnet-4-6", "input_tokens": N, "output_tokens": N, "duration_ms": N }

This endpoint answers from the model and the agent's configured prompt only — it does not automatically retrieve from the CKG. For agents that should cite ingested knowledge, use Company Brain (POST /api/v1/brain/chat), which embeds the query, searches CKG nodes semantically, and returns a cited answer.

What's next

  • Agents — lifecycle states, best practices, and what belongs in system_prompt vs. enforced governance
  • Memory Types — the five memory layers and when each one matters
  • Document Vault, Wiki, and Company Brain are covered in-app under Vault, Wiki, and Brain in the sidebar