Knowledge API

A knowledge graph service for claims, predicates, perspectives, entity resolution, provenance tracking, and invariant monitoring. Build structured knowledge bases with multi-perspective conflict detection.

Sources

Sources represent the origin of knowledge -- documents, APIs, human input, or agent observations. Every claim traces back to a source for provenance.

MethodPathDescription
GET /v1/knowledge/sources List sources (optional namespace filter)
POST /v1/knowledge/sources Create a source
DELETE /v1/knowledge/sources/{id} Soft-delete a source

SDK Examples

// Create a source
const source = await client.knowledge.createSource({
  namespace: 'product-docs',
  name: 'API Reference v2',
  kind: 'document',
  url: 'https://docs.example.com/api/v2',
});

// List sources by namespace
const sources = await client.knowledge.listSources('product-docs');
// Rust SDK
use kapable_sdk::knowledge::types::*;

let source = client.knowledge().create_source(CreateSourceRequest {
    namespace: Some("product-docs".into()),
    name: "API Reference v2".into(),
    kind: Some("document".into()),
    url: Some("https://docs.example.com/api/v2".into()),
    ..Default::default()
}).await?;

let sources = client.knowledge().list_sources(ListSourcesQuery {
    namespace: Some("product-docs".into()),
    ..Default::default()
}).await?;

Pages

Pages are named entities within a source. They provide the structure for organizing claims and edges in the knowledge graph.

MethodPathDescription
GET /v1/knowledge/pages List pages (canonical only)
POST /v1/knowledge/pages Create a page
POST /v1/knowledge/pages/merge Merge two pages (dedup)

SDK Examples

// Create a page
const page = await client.knowledge.createPage({
  source_id: source.id,
  title: 'Authentication',
  namespace: 'product-docs',
});

// Merge duplicate pages
await client.knowledge.mergePages({
  keep_id: canonicalPageId,
  merge_id: duplicatePageId,
});
// Rust SDK
let page = client.knowledge().create_page(CreatePageRequest {
    source_id: source.id,
    title: "Authentication".into(),
    namespace: Some("product-docs".into()),
    ..Default::default()
}).await?;

client.knowledge().merge_pages(MergePagesRequest {
    keep_id: canonical_page_id,
    merge_id: duplicate_page_id,
}).await?;

Claims

Claims are the core knowledge unit -- subject-predicate-object triples with confidence scores, perspectives, and provenance. Claims can be retracted, searched, and compared across perspectives.

MethodPathDescription
GET /v1/knowledge/claims List claims with optional filters
POST /v1/knowledge/claims Create a claim (supports dry_run query param)
GET /v1/knowledge/claims/{id} Get a single claim
POST /v1/knowledge/claims/{id}/retract Retract a claim
GET /v1/knowledge/claims/similar Search claims (lexical, vector, or hybrid)
GET /v1/knowledge/claims-by-perspective Compare claims by perspective for a (subject, predicate)

SDK Examples

// Create a claim
const claim = await client.knowledge.createClaim({
  subject: 'kapable-auth',
  predicate: 'supports',
  object: 'OAuth 2.0',
  confidence: 0.95,
  source_id: source.id,
  perspective_id: perspectiveId,
});

// Dry-run: check what would happen without persisting
const outcome = await client.knowledge.createClaim(
  { subject: 'kapable-auth', predicate: 'supports', object: 'SAML' },
  { dryRun: true },
);

// Search claims
const similar = await client.knowledge.searchClaims({
  query: 'authentication protocol',
  mode: 'hybrid',
  limit: 10,
});

// Compare perspectives
const views = await client.knowledge.listClaimsByPerspective({
  subject: 'kapable-auth',
  predicate: 'supports',
});

// Retract a claim
await client.knowledge.retractClaim(claim.id, {
  reason: 'Superseded by newer information',
});
// Rust SDK
let claim = client.knowledge().create_claim(
    CreateClaimRequest {
        subject: "kapable-auth".into(),
        predicate: "supports".into(),
        object: "OAuth 2.0".into(),
        confidence: Some(0.95),
        source_id: Some(source.id),
        perspective_id: Some(perspective_id),
        ..Default::default()
    },
    CreateClaimQuery { dry_run: None },
).await?;

let similar = client.knowledge().search_claims(SearchClaimsQuery {
    query: Some("authentication protocol".into()),
    mode: Some("hybrid".into()),
    limit: Some(10),
    ..Default::default()
}).await?;

let views = client.knowledge().list_claims_by_perspective(CompareByPerspectiveQuery {
    subject: "kapable-auth".into(),
    predicate: "supports".into(),
}).await?;

client.knowledge().retract_claim(claim_id, RetractClaimRequest {
    reason: "Superseded by newer information".into(),
}).await?;

Claim Confidence Evidence

Attach evidence records that justify a claim's confidence score. Each evidence record documents why the confidence was set to a particular value.

MethodPathDescription
GET /v1/knowledge/claims/{id}/confidence-evidence List confidence evidence for a claim
POST /v1/knowledge/claims/{id}/confidence-evidence Create confidence evidence for a claim
GET /v1/knowledge/claim_confidence_evidence List all confidence evidence (global)

Claim Meta and Derivations

Claim meta (reification) attaches metadata to claims. Derivations link claims that were derived from other claims.

MethodPathDescription
GET /v1/knowledge/claim_meta List claim meta records
POST /v1/knowledge/claim_meta Create claim meta
GET /v1/knowledge/claim_derivations List claim derivations
POST /v1/knowledge/claim_derivations Create claim derivation links

Edges

Edges connect pages in the knowledge graph (e.g. "references", "depends_on").

MethodPathDescription
GET /v1/knowledge/edges List edges with optional filters
POST /v1/knowledge/edges Create an edge between pages

SDK Examples

// Create an edge between pages
const edge = await client.knowledge.createEdge({
  source_page_id: authPageId,
  target_page_id: oauthPageId,
  predicate: 'depends_on',
});
// Rust SDK
let edge = client.knowledge().create_edge(CreateEdgeRequest {
    source_page_id: auth_page_id,
    target_page_id: oauth_page_id,
    predicate: "depends_on".into(),
    ..Default::default()
}).await?;

Predicates

Predicates define the vocabulary for claims and edges. The predicate ontology supports parent/child relationships and inverse predicates.

MethodPathDescription
GET /v1/knowledge/predicates List all predicates
GET /v1/knowledge/predicates/{name}/ontology Get predicate ontology (parents, children, inverse)

SDK Examples

// List all predicates
const predicates = await client.knowledge.listPredicates();

// Get ontology for a predicate
const ontology = await client.knowledge.predicateOntology('supports');
// { name: 'supports', inverse: 'supported_by', parents: [...], children: [...] }
// Rust SDK
let predicates = client.knowledge().list_predicates().await?;

let ontology = client.knowledge().predicate_ontology("supports").await?;
// ontology.name, ontology.inverse, ontology.parents, ontology.children

Canonical Entities

Entity resolution merges duplicate references into canonical entities. Auto-merge candidates are surfaced for review and decision.

MethodPathDescription
GET /v1/knowledge/canonical_entities List canonical entities
POST /v1/knowledge/canonical_entities/resolve Resolve (or create) a canonical entity
GET /v1/knowledge/canonical_entities/merge_candidates List merge candidates
POST /v1/knowledge/canonical_entities/merge_candidates/{id}/decide Decide a merge candidate
POST /v1/knowledge/canonical_entities/merge_candidates/{id}/unmerge Unmerge a previously merged candidate

SDK Examples

// Resolve an entity (find or create canonical)
const result = await client.knowledge.resolveCanonicalEntity({
  name: 'Kapable Auth Service',
  namespace: 'services',
});

// List merge candidates
const candidates = await client.knowledge.listMergeCandidates({
  status: 'pending',
});

// Accept a merge
await client.knowledge.decideMergeCandidate(candidateId, {
  decision: 'merged',
});

// Undo a merge
await client.knowledge.unmergeMergeCandidate(candidateId, {
  reason: 'False positive -- different services',
});
// Rust SDK
let result = client.knowledge().resolve_canonical_entity(ResolveCanonicalEntityRequest {
    name: "Kapable Auth Service".into(),
    namespace: Some("services".into()),
    ..Default::default()
}).await?;

let candidates = client.knowledge().list_merge_candidates(ListMergeCandidatesQuery {
    status: Some("pending".into()),
    ..Default::default()
}).await?;

client.knowledge().decide_merge_candidate(candidate_id, DecideMergeCandidateRequest {
    decision: "merged".into(),
    ..Default::default()
}).await?;

client.knowledge().unmerge_merge_candidate(candidate_id, UnmergeRequest {
    reason: Some("False positive -- different services".into()),
}).await?;

Perspectives

Perspectives represent viewpoints from which claims are made. Different agents, teams, or documents may hold different perspectives on the same subject-predicate pair.

MethodPathDescription
GET /v1/knowledge/perspectives List all perspectives
GET /v1/knowledge/perspectives/{id} Get a perspective by ID

Provenance

Track the provenance chain for sources -- where knowledge came from and how it was transformed.

MethodPathDescription
GET /v1/knowledge/source_provenance List source provenance records
GET /v1/knowledge/sources/{id}/provenance-graph BFS provenance graph for a source

SDK Examples

// Get the provenance graph for a source
const graph = await client.knowledge.sourceProvenanceGraph(sourceId, {
  depth: 3,
});
// graph.nodes, graph.edges -- ready for visualization
// Rust SDK
let graph = client.knowledge().source_provenance_graph(source_id, Some(3)).await?;
// graph.nodes, graph.edges

Invariants and Assay

The Knowledge service runs periodic invariant checks (assay runs) to detect data quality issues, contradictions, and anomalies.

MethodPathDescription
GET /v1/knowledge/invariants List invariant definitions
GET /v1/knowledge/assay_runs List assay run results

Tensions

Detect contradictions (tensions) between claims. Useful for surfacing conflicting information from different perspectives.

MethodPathDescription
GET /v1/knowledge/tensions Detect tensions (contradictions) between claims

SDK Examples

// Detect tensions
const tensions = await client.knowledge.detectTensions({
  namespace: 'product-docs',
});
for (const t of tensions.items) {
  console.log(`Tension: ${t.claim_a.subject} vs ${t.claim_b.subject}`);
  console.log(`  Predicate: ${t.predicate}`);
}
// Rust SDK
let tensions = client.knowledge().detect_tensions(TensionsQuery {
    namespace: Some("product-docs".into()),
    ..Default::default()
}).await?;
for t in &tensions.items {
    println!("Tension: {} vs {}", t.claim_a.subject, t.claim_b.subject);
}