Developer Integration Guide

CueCrux stays open where it unlocks innovation (contracts, receipts, and artefacts are verifiable), and controlled where it safeguards trust (provenance, licences, and cost budgets).

This page helps developers integrate CueCrux into their own products by clarifying the difference between client‑facing WebCrux APIs and the server‑only Engine SDK, outlining installation steps, and summarising best practices. Throughout this guide you’ll see references to the platform’s cost‑conditioned cascades (C³), CROWN receipts, and QUORUM (MiSES) evidence selection; these are the guardrails that keep integrations reproducible and auditable.


Access Posture for External Developers

  • Everything runs over HTTPS. You integrate through the Web API (or your own BFF that proxies it); no VPN, Docker network, or repo access is required.
  • Your infrastructure stays under your control. Deploy BFF routes, schedulers, or edge workers inside your environment; they call CueCrux using organisation-scoped API keys.
  • Advanced features stay proxied. WatchCrux, FactoryCrux, or AgentCrux workflows show up as managed APIs or queues when your contract allows them you never plug straight into CueCrux’s private network.

Keeping this boundary clear makes security conversations simple: you own the outer experience, while CueCrux runs the trust stack.


Choosing Your Path

Most integrations fall into one of two flows:

Use caseHow to call CueCrux
Browser or mobile appCall your own WebCrux API (/api/answers, /api/search) from the client. WebCrux runs as your Backend‑for‑Frontend (BFF) and proxies requests to the Engine.
Server, CLI or scheduled jobUse the Engine SDK (@cuecrux/sdk or @cuecrux/engine-client) on the server or edge only. Never embed Engine API keys in client‑side code.

In other words, the browser never talks directly to the Engine your BFF does. This separation keeps API keys and provenance checks within your trusted boundary.


Quick Start: WebCrux API

WebCrux exposes a minimal REST surface (POST /api/answers, GET /api/search, GET /api/healthz) that your client app can call without any secret keys. Under the hood, WebCrux proxies these calls to the Engine over CueCrux-managed infrastructure, so you never need direct access to the internal network. Here is a simple composable for Nuxt/Vue that wraps the call:

// composables/useAnswers.ts
export const useAnswers = () => {
  const ask = async (
    q: string,
    mode: 'light' | 'verified' | 'audit' = 'verified',
    freshness?: { max_snapshot_age?: string }
  ) => {
    return await $fetch('/api/answers', {
      method: 'POST',
      body: { q, k: 10, mode, freshness }
    });
  };
  return { ask };
};

On the server, create a matching route that forwards the call to the Engine using the SDK. Your API route holds the Engine API key and never exposes it to the browser:

// server/api/answers.post.ts (Nuxt/Nitro)
import { createClient } from '@cuecrux/engine-client';

const engine = createClient({
  baseUrl: process.env.ENGINE_BASE_URL!,
  apiKey: process.env.ENGINE_API_KEY!,
});

export default defineEventHandler(async (event) => {
  const body = await readBody<{
    q: string;
    k?: number;
    mode?: 'light' | 'verified' | 'audit';
    freshness?: { max_snapshot_age?: string };
  }>(event);
  const res = await engine.answers({
    q: body.q,
    k: body.k ?? 10,
    mode: body.mode ?? 'verified',
    freshness: body.freshness,
  });
  return res;
});

This BFF pattern ensures that provenance receipts are validated server‑side and lets you enrich or throttle requests. On error, map Engine status codes (e.g. 429 for rate limiting, 409 for contradictions) to user‑friendly messages before returning them to the client.


History & Saved APIs

The WebCrux master plan requires first-class history and saved surfaces (§7 Networking & BFF Contracts). External developers hit those via the BFF just like /api/answers.

/api/history

  • GET /api/history: Paginates the user’s previous queries. Supports filters (mode, org_id, from, to, tag).
  • POST /api/history: Optional hook if you run custom schedulers (e.g., nightly replays). Provide { q, mode, freshness, metadata } and the BFF records the entry after the Engine run succeeds.
  • Rate limit: 60 req/min per user; bulk exports use the SupportCrux ticket flow instead.
const history = await $fetch('/api/history', {
  query: { mode: 'verified', limit: 20, cursor }
});
history.items.forEach((entry) => {
  console.log(entry.answer_id, entry.trust.findings_state);
});

Response fields align with the Postgres schema from the master plan: id, answer_id, mode, requested_at, org_id, findings_state, plus a summary hash for cache validation.

/api/saved

  • GET /api/saved: Returns folders/tags plus the saved answer snapshot, CROWN snapshot ID, and latest Findings verdict.
  • POST /api/saved: Body { answer_id, title, tags }; the BFF stores metadata and links the record to the user/org.
  • DELETE /api/saved/:id: Soft-deletes and cascades tag entries; receipts remain immutable in Engine.
  • Rate limit: 30 write ops/min per user; reads share the /api/history pool.

Example save call inside Nuxt:

await $fetch('/api/saved', {
  method: 'POST',
  body: { answer_id: ans.answer_id, title: 'EU ESG scope 3', tags: ['esg','2025'] }
});

Data Model Snapshot

TableKey FieldsNotes
queriesid, user_id, org_id, mode, requested_at, answer_idRecords every Ask invocation so history filters remain fast.
answers_savedid, user_id, answer_id, snapshot_id, tags, created_atStores metadata only; Engine remains the source of the actual artefacts.
entitlementsorg_id, feature_key, enabled, planGates whether an org can use shared history or export trust reports.

Because history and saved APIs sit behind the same HTTPS BFF, external developers can offer rich dashboards (re-run buttons, Findings badges, workspace filters) without maintaining separate stores.


Server‑Side Integration: Engine SDK

The Engine SDK comes in two flavours. Choose the wrapper that matches your needs:

PackageCharacteristicsTypical usage
@cuecrux/sdkLightweight wrapper with Zod validation, timeout/abort support, limited retries and per‑request headers. Throws if used in a browser context.Preferred for simple calls from Node, edge functions or BFF routes.
@cuecrux/engine-clientFully typed client generated from OpenAPI. Exposes additional methods for receipts, provenance and trust reports.Use when you need strict type safety or endpoints such as receipt(), provenance(), or trustReport().

Installation

pnpm add @cuecrux/sdk zod
pnpm add @cuecrux/engine-client cross-fetch

@cuecrux/sdk peers on your project’s Zod version; @cuecrux/engine-client peers on cross-fetch for universal fetch support.

Creating a Client

Here’s how to create a client with sensible defaults. Because the SDK enforces server‑only credentials, it will throw if it detects a browser context with an API key.

import { createClient } from '@cuecrux/sdk';

const sdk = createClient({
  baseUrl: process.env.ENGINE_BASE_URL!,
  apiKey: process.env.ENGINE_API_KEY!,
  timeoutMs: 5000,
  retries: 1,
});

const res = await sdk.answers({ q: 'UK corporation tax changes for 2025', k: 10, mode: 'verified' });
console.log(res.summary);

For full API coverage use @cuecrux/engine-client:

import { createEngineClient } from '@cuecrux/engine-client';
import fetch from 'cross-fetch';

const engine = createEngineClient(process.env.ENGINE_BASE_URL!, fetch);

const ans = await engine.answers({ q: 'UK corporation tax changes for 2025', k: 10, mode: 'verified' });
const rec = await engine.receipt(ans.answer_id);
const prov = await engine.provenance(rec.primary_artifact_id);
const reportHtml = await engine.trustReport(ans.answer_id, { format: 'html' });

API Surface

  • sdk.health() → GET /healthz; returns { ok: boolean; status: number }.
  • sdk.answers(body, headers?) → POST /v1/answers; validates the body and returns a structured answer.
  • sdk.search(params, headers?) → GET /v1/search; validates query parameters and returns search results.
  • engine.receipt(answerId) → GET /v1/answers/{id}/receipt.
  • engine.provenance(artifactId) → GET /v1/provenance/{artifactId}.
  • engine.trustReport(answerId, { format }) → GET /v1/answers/{id}/trust-report with html, pdf or json output.

Requests & Validation

Common fields include a query string (q), optional result count (k between 1 and 50) and a mode ('light' | 'verified' | 'audit'). The lightweight SDK validates inputs with Zod; the typed client relies on TypeScript generics and server validation. On invalid input the SDK throws early, helping you catch mistakes before hitting the network.

Security & Environment

Keep Engine credentials on the server. The SDK will refuse to run client‑side if an API key is present. Recommended patterns include:

  • SPA → BFF: your own API routes hold the key; the browser calls those routes.
  • SSR/Edge: inject the API key from secure environment variables; never serialize it into HTML or JavaScript bundles.
  • Multi‑tenant: attach tenant and trace headers per request (e.g. x-tenant, x-trace) as shown below.
  • External by default: assume every call traverses the public internet; apply TLS pinning/CDN rules, monitor latency, and set explicit budgets for outbound traffic.

Resilience & Error Handling

The SDK uses AbortController to enforce timeouts (default 5000 ms). It retries transient errors (502, 503, 504) up to the configured limit and provides structured error objects that include the HTTP status. Use the error union to branch your logic:

try {
  const result = await sdk.answers({ q: 'corporation tax', mode: 'verified' });
} catch (err: any) {
  switch (err.kind) {
    case 'RateLimited':
      // back off and retry later
      break;
    case 'StaleSnapshot':
      // widen freshness or request newer data
      break;
    case 'Contradiction':
      // display a warning to the user
      break;
    default:
      throw err;
  }
}

Limit yourself to a couple of retries with jitter and respect Retry‑After headers. If your circuit breaker opens for more than 30 seconds, surface a “service degraded” message to users.

Freshness & Time‑Travel Queries

CueCrux lets you bound how recent the evidence should be (via freshness) or query a historical snapshot (via as_of). Freshness values use ISO‑8601 durations (e.g. P7D for seven days). Examples:

// Fresh evidence within the last week
await sdk.answers({ q: 'Current UK corporation tax thresholds', k: 10, mode: 'verified',
  freshness: { max_snapshot_age: 'P7D' }
});

// Historical snapshot as of 30 June 2025
await engine.answers({ q: 'Corporation tax guidance', k: 10, mode: 'audit', as_of: '2025-06-30T00:00:00Z' });

Mode guidelines:

  • light: fastest responses, typical freshness ≤ 14 days.
  • verified: balanced, recommended default, freshness ≤ 7 days.
  • audit: full receipts and counterfactuals, freshness ≤ 24 hours.
    If a request falls outside its freshness window, the Engine returns a StaleSnapshot error.

Headers & Multi‑Tenancy

You can define default headers when creating a client and override them per request. For example:

const sdk = createClient({
  baseUrl: process.env.ENGINE_BASE_URL!,
  apiKey: process.env.ENGINE_API_KEY!,
  headers: { 'x-trace': 'svc-A' }
});

// Override on a single call
await sdk.answers({ q: 'UK corp tax 2025' }, { 'x-tenant': 'acme-eu' });
await sdk.search({ q: 'accounting periods' }, { 'x-tenant': 'acme-eu' });

Health Gating & Compatibility

Before serving traffic, gate on the Engine’s health status:

const { ok } = await sdk.health();
if (!ok) throw new Error('Engine not healthy');

Use the /healthz endpoint to check the Engine’s build version and compatibility matrix before upgrading dependencies. Apply semantic versioning: patch releases are bug fixes, minor releases add fields, and major releases may break compatibility with at least a two‑week grace window.


Advanced Features

Extension API (Overview)

The Extension API allows partners to ingest new evidence sources, implement custom validators or add domain‑specific agents without breaking the chain of proof. All extensions run server‑side under BFF headers and must produce artefacts that pass licence and provenance checks. Use this path when you need to integrate proprietary feeds or validators; contact the CueCrux team to register your extension and obtain signing keys.

Private Stack (Overview)

For enterprises requiring strict data residency or secrecy, a Private Stack provides an isolated namespace, database schema and object storage while still federating proof hashes to the public graph. Each tenant runs under its own mTLS gateway and retains full control over its budget and extensions. This option is suitable for regulated industries (finance, pharma, government) where internal documents must remain private but statements still need verifiable receipts.


Example Patterns

  • Product UI – embed a proof capsule next to key numbers in a dashboard. Clicking reveals QUORUM (MiSES) citations (minimal evidence set), timestamps and a “View Receipt” link.
  • Compliance tool – verify receipts upon ingest and store verification status alongside policy records.
  • Editorial CMS – lint outgoing articles for missing citations and automatically attach provenance cards.
  • Scientific publishing – require CueCrux receipts for quantitative claims; reviewers click receipts to audit sources.
  • Vendor data pipeline – publish an ingest adaptor so clients safely index feeds with licence capture and earn Crux.
  • Enterprise wiki – integrate the SDK so pages display trust badges and auto‑banner stale or retracted sources.
    Each pattern builds on the same fundamentals: call the Engine via a BFF, verify receipts, respect budgets and show trust indicators.

Production Checklist

  • Engine API keys never reach the browser.
  • WebCrux routes enforce health gating before serving traffic.
  • Timeouts and limited retries configured per service‑level objective.
  • Per‑request headers set for tenant or trace where applicable.
  • Receipts verified for user‑visible answers; trust badges surfaced accordingly.
  • Types validated at compile time (engine-client) or runtime (sdk + Zod).
  • Semantic versions monitored; upgrade on minor releases; test major releases in a sandbox first.

Conclusion

Integrating CueCrux as a developer means balancing openness and control. Use the WebCrux API for your front‑end, rely on the Engine SDK for trusted server calls, and always respect the provenance and budgeting mechanisms built into the platform. With these guardrails in place you can innovate confidently entirely over HTTPS knowing every answer is backed by verifiable evidence without ever touching CueCrux’s private infrastructure.