Scout / API reference

The runtime interface, not a placeholder.

This reference documents the Express interface currently implemented by ProjectHub/Scout. It describes route behavior, request and response fields, diagnostics, browser-local inference support, rate/CORS behavior, failure semantics, and compatibility limits. It does not claim a public multi-tenant API-key product or external SLA.

Primary routePOST /api/chat
Request limit600 message characters
App rate control20 chat requests / minute / IP
Request deadline15 seconds maximum
No API sections match that search.
01 / Contract

What this API is.

Scout currently exposes an application runtime API for ProjectHub Recruiter Alpha. The route surface is real and usable by the ProjectHub frontend and engineering tooling, but it is not documented here as a stable public developer platform.

September 15 release: the runtime source is now master@7d011708, exact-tree equivalent to develop@e74ac22b. The semantic-planning/identity/validation changes are internal runtime behavior; they do not convert these application endpoints into a versioned public multi-tenant API product.
Current

Application runtime

Chat, health, diagnostics, retrieval, client-local packet validation, logs, and optional cost telemetry are implemented by the Express backend.

Not claimed

Public API product

No self-service API-key account system, public versioning guarantee, published external SLA, or metered developer billing contract is claimed.

Precedence

Executable source wins

When older prose disagrees with current server code or runtime facts, this reference follows current executable behavior.

Documentation drift: the older repository API guide still references routes and Ollama-era behavior that are not all present in current develop. This page inventories the current server source instead.
September 15 released source: PR #31 integrated semantic-reliability and tenant-portability into develop@e74ac22b; PR #32 promoted the exact tree 92b4d149 to master@7d011708. ProjectHub-dev main 201beb9c records e74ac22b as its staging source.
September 5 released source: production b071e4e4 and protected integration 4f5ee971 have different Git ancestry but the same Git tree a0066cc8. ProjectHub-dev records 4f5ee971 as its staging source. PR #29 used an ancestry-preserving release commit rather than forcing the conflicting direct develop→master PR #25.
02 / Environments

Runtime environments.

The release specification separates production and development staging. These are application endpoints, not customer-specific base URLs or a versioned public API gateway.

EnvironmentBackend baseSource role
Productionhttps://projecthub-chat.bradleymatera.devProjectHub:master
Development staginghttps://dev.projecthub-chat.bradleymatera.devProjectHub:develop
Localhttp://127.0.0.1:3000 by defaultCurrent checkout and local environment
Branch and runtime are separate facts. The backend exposes build provenance in /health; use that rather than assuming a hostname proves which commit is running.
03 / Transport

JSON, CORS, limits.

JSON body

1 MB Express parser ceiling

The server registers express.json({ limit: '1mb' }). Individual chat messages are separately capped at 600 characters.

Chat rate limit

20 requests/minute/IP by default

RATE_LIMIT_MAX can override the default. Standard rate-limit headers are enabled for /api/chat.

CORS methods

GET, POST, OPTIONS

Configured origins are allowlisted. Localhost and 127.0.0.1 origins are accepted for development.

Headers

Content-Type + Authorization accepted

The server CORS configuration permits both headers, but current source does not expose a self-service API-key authentication product.

Do not infer authentication from the allowed Authorization header. A permitted CORS header is not the same thing as an implemented public authentication scheme.
04 / Route inventory

Routes present in the September 15 released source.

This table deliberately omits routes that only survive in older documentation. In particular, /api/think and /api/stats are not listed as current server routes because they are not present in the current server source reviewed for this page.

MethodPathPurposeAudience
GET/Basic service/status identityRuntime
POST/api/chatPrimary Scout conversation requestProjectHub frontend
GET/healthDetailed build/runtime/usage stateOperations
GET/health/liveProcess liveness probeDeploy/operations
GET/health/readyModel + knowledge readiness probeDeploy/operations
GET/api/retrieveQuery-understanding and retrieval diagnosticDevelopment
GET/api/diagnoseLegacy/local generation-validation diagnosticEngineering
GET/api/agent-probeAgent/model reachability and structured-output probeEngineering
GET/api/knowledge-healthKnowledge coverage and legacy learning telemetryEngineering
POST/api/client-packetPrepare client-safe evidence packet for browser generationExperimental/browser-local
POST/api/client-validateValidate a browser-generated answer against stored evidenceExperimental/browser-local
GET/api/client-statusReport browser-local inference support metadataExperimental/browser-local
GET/api/chat-logGrouped persisted chat-log telemetryOperations
GET/api/costsCost ledger snapshot or explicit offline stateOperations
05 / Primary route

POST /api/chat

The chat route owns the end-to-end request deadline, conversation-state lookup, policy classification, optional query rewrite, local retrieval, agent execution, validation, response shaping, telemetry, and memory update.

Request body

FieldTypeRequiredBehavior
messagestringYes for normal chatTrimmed; empty is rejected; maximum 600 characters.
sessionIdstringNoTruncated to 128 characters and used for server-owned conversation state and memory.
historyarrayNoRecent conversation supplied by the client; server-side helpers sanitize/bound it before use.
actionstringNoclear clears conversation memory/state for the supplied session and returns immediately.
gateDebugbooleanNoDetailed diagnostics require both server SCOUT_GATE_DEBUG=true and request gateDebug:true (or query gateDebug=1). Debug turns bypass response-cache reads and writes.
Request
curl -sS https://projecthub-chat.bradleymatera.dev/api/chat \
  -H 'Content-Type: application/json' \
  -d '{
    "message": "Which project best demonstrates debugging?",
    "sessionId": "example-tab-1",
    "history": [
      {
        "user": "What is Bradley strongest at?",
        "assistant": "..."
      }
    ]
  }'

Execution sequence

Deadline starts immediately.The route caps REQUEST_DEADLINE_MS at 15,000 ms and propagates an abort signal into generation.
Input and knowledge are checked.Message length, session id, history, knowledge readiness, and optional clear action are resolved first.
Conversation policy is classified.Control turns such as greetings or profile updates can avoid normal retrieval rewriting; substantive turns can be rewritten from server-owned context.
Cache/direct-KB paths are evaluated.Direct KB is opt-in. No-history responses can use the response cache when present and fresh.
Retrieval prepares evidence.Current agent mode retrieves up to 10 BM25/RRF candidates before calling the RAG-primary agent.
Generation and validation run.The configured inference provider produces prose; the agent returns validation, evidence, generation-call and repair metadata.
Format and state are finalized.The server shapes format without authoring replacement prose, records telemetry, remembers the turn, and updates structured session state.
06 / Response

Success payload.

The exact metadata varies by path, but current chat responses expose more than visible prose. Clients should treat fields other than reply as runtime metadata, not a frozen public schema.

Representative success shape
{
  "ok": true,
  "reply": "...",
  "provider": "cloudflare",
  "model": "@cf/meta/llama-3.1-8b-instruct-fast",
  "fallback": false,
  "grounded": false,
  "proseSource": "MODEL_GENERATION",
  "pipeline": ["knowledge-loaded", "policy:...", "cache-miss", "scout-agent-lite:...", "shaped"],
  "contract": {
    "intent": "...",
    "directAnswer": "...",
    "factState": "TRUE | FALSE | UNKNOWN",
    "evidenceStrength": "...",
    "claimCeiling": "..."
  },
  "sessionMemory": {
    "turns": 5,
    "retained": true
  },
  "agent": {
    "agentMode": "lite",
    "inferenceProvider": "cloudflare",
    "generationCalls": [],
    "retrievalCandidates": [],
    "selectedEvidence": []
  }
}

Prose source

MODEL_GENERATION

Generated and accepted

Visible chatbot prose came from the configured model and passed the runtime path.

DIRECT_KB

Canonical direct answer

Possible only when the direct-KB short-circuit is explicitly enabled and semantically applicable.

TECHNICAL_ERROR

Failure response

The service did not return a normal chatbot answer because generation, validation, or infrastructure failed.

Legacy field naming exists. Some fields such as local.only, mode, and older provider labels survive from earlier architecture phases. Use provider, model, proseSource, contract, agent, and /health.buildEnv together when diagnosing current behavior.
07 / Failure contract

Check ok, not just HTTP status.

Current runtime behavior mixes HTTP status codes and JSON-level error states. Some operational failures return a JSON body with ok:false using the default HTTP 200 status.

ConditionHTTP behaviorPayload signal
Missing chat message400{ error: "Missing message." }
Message over 600 chars400{ error: "Message is too long." }
Chat rate limit exceeded429{ error: "Too many chat requests. Please slow down." }
Knowledge unavailableJSON responseok:false, TENANT_KNOWLEDGE_UNAVAILABLE
Inference unavailable / deadlineJSON responseok:false, INFERENCE_UNAVAILABLE
Agent engine unavailableJSON responseok:false, AGENT_ENGINE_UNAVAILABLE
Unhandled chat errorJSON responseok:false, INTERNAL_ERROR
Readiness warming503ok:false, status:"warming"
Client-side success check
const response = await fetch(base + '/api/chat', options);
const payload = await response.json();

if (!response.ok || payload.ok === false) {
  throw new Error(payload.error || `HTTP ${response.status}`);
}

console.log(payload.reply);
08 / Health

Three different health surfaces.

GET /health/live

Process liveness

Returns HTTP 200 with { ok:true, status:"alive" } when the process is running.

GET /health/ready

Readiness

Returns 200 only when both modelVerified and knowledgeReady are true; otherwise 503.

GET /health

Detailed runtime state

Includes build provenance, provider/model configuration, request deadline, counters, provider health, recent sessions, memory, agent state, and knowledge/retrieval telemetry.

Readiness check
curl -fsS https://projecthub-chat.bradleymatera.dev/health/ready
Deployment verification: use /health.buildEnv.sourceCommit to verify what was actually deployed. A healthy hostname alone does not prove source provenance.
09 / Diagnostic

GET /api/retrieve

The server labels this route as a dev-only retrieval testing endpoint. It exposes query understanding plus current BM25 behavior without running normal chat generation.

Query parameterBehavior
qRequired query string. Missing value returns HTTP 400.
hOptional JSON-encoded history. With history, retrieval uses fused local BM25/RRF views; without history, direct BM25 is used.
Standalone retrieval
curl -sS 'http://127.0.0.1:3000/api/retrieve?q=what%20did%20he%20build'

The response exposes rewritten, normalized, intent, retrievalMethod, BM25 results, and the legacy substring fallback results for comparison.

10 / Diagnostics

Model probes are engineering surfaces.

GET /api/diagnose

This endpoint still probes the local Ollama URL, attempts a bounded generation when reachable, validates the result, and returns a short preview. That makes it useful for the local-development path, but it should not be read as the authoritative production-provider health check.

GET /api/agent-probe

This endpoint runs the agent probe through the current model router, reports engine/agent mode, reachability, structured-output capability, latency, available/pinned local models, and the session-state store size.

Provider distinction: current production runtime facts identify Cloudflare Workers AI as normal generation. The presence of Ollama-oriented diagnostics reflects the retained dev/evaluation path, not an Ollama-only production architecture.
Per-turn gate diagnostics are opt-in twice: /api/chat exposes gate-debug detail only when the server has SCOUT_GATE_DEBUG=true and the request explicitly opts in with gateDebug: true (or query gateDebug=1). Authorized debug responses are Cache-Control: no-store and bypass normal response-cache reuse. A public request cannot enable diagnostics by itself.
11 / Knowledge

GET /api/knowledge-health

This diagnostic walks the loaded knowledge object, reports populated/empty field coverage, aggregates topic/gap telemetry, and includes legacy learned-answer structures that remain for compatibility.

Useful current data

Coverage and topic diagnostics

Knowledge version, last update, field coverage, empty paths, hot topics, uncovered topics, and bundled/local learned records.

Legacy compatibility

Learning fields remain

The current server initializes legacy learning objects so health responses remain well-formed even though Think Mode/background learning has been removed from runtime.

Removed runtime behavior: do not interpret learning telemetry fields as proof that background Think Mode is active. Current server comments explicitly state it was removed.
12 / Experimental

Browser-local packet/validate flow.

Current develop contains an experimental server-assisted browser-local path. The server still owns retrieval/evidence preparation and final validation; the browser can supply the generation step.

POST /api/client-packetAccepts message and sessionId, retrieves evidence, executes the deterministic route/tool, builds a client-safe prompt packet, stores the server-side evidence under a generated runId, and returns only the client-safe packet.
Browser generates locally.The current status endpoint describes the experimental target as Qwen2.5 0.5B Instruct via Transformers.js v4 + WebGPU.
POST /api/client-validateThe browser returns runId + answer. The server validates that answer against the same stored evidence and checks forbidden claims before updating session state.
ConstraintCurrent behavior
Packet TTL60 seconds in the in-memory packet store.
Message lengthMaximum 600 characters for /api/client-packet.
Answer lengthValidation truncates the submitted answer to 600 characters.
Expired run id/api/client-validate returns HTTP 404 with verdict:"expired".
Production statusExperimental; not represented as the normal production generation path.
13 / Operations

Operational telemetry.

/health and /api/chat-log expose internal runtime/usage information. These are operational surfaces, not a public analytics API contract.

/health

Runtime snapshot

Build source, provider/model selection, latency/deadline configuration, aggregate request counters, provider health, memory counts, recent sessions, and agent metadata.

/api/chat-log

Grouped chat history

Groups persisted log records by truncated session id and returns up to 100 sessions with message counts, timing, topics, provider mix, questions, replies, and latency.

Privacy/operations note: chat-log and recent-session data are operational records. Their presence in the current application backend does not make them appropriate customer-facing endpoints in a future generalized Scout API.
14 / Metering

GET /api/costs

The route is always mounted, but its behavior depends on COST_TRACKER.

Tracker enabled

Ledger snapshot + insights

Returns the cost-ledger snapshot and computed insights. The backend also samples VM compute and local state-file storage every 60 seconds.

Tracker disabled

Explicit offline payload

Returns HTTP 200 with { ok:false, offline:true, reason:"COST_TRACKER is not enabled on this backend" } rather than a 404.

Known source-truth debt: current executable provider/accounting code is exact-model and null-safe, but data/scout-runtime-knowledge.json is still marked lastVerified: 2026-08-21 and retains the superseded sentence assigning 4,119 / 34,868 to Scout's normal -fast model. This site treats that sentence as stale and follows executable provider/accounting code instead.
Actual, estimated, and unknown are different states: actualNeurons is provider-reported usage when available. estimatedNeurons is calculated only when the exact model has a verified rate. For @cf/meta/llama-3.1-8b-instruct-fast, token-derived usage remains unknown when no provider actual value exists. Unknown is not zero and is not a verified $0 cost.
15 / Security boundary

Current application controls.

HTTP

Helmet + CORS

Helmet is enabled with selected policy options, and CORS is restricted to configured origins plus local development origins.

Abuse control

Per-IP chat rate limit

The primary chat route is rate-limited independently from Cloudflare's account-level AI allocation.

Input

Bounded JSON/message sizes

The JSON parser has a 1 MB cap and chat/client-packet messages have a 600-character cap.

Scout also has application-level response-policy, safety, grounding, relationship, provenance and false-claim controls, but those are answer-quality/security layers rather than HTTP authentication.

No public auth contract: this reference does not describe a customer API-key scheme because current ProjectHub source does not define one as a public product interface.
16 / Compatibility

No frozen public schema yet.

The current interface evolves with ProjectHub. A future commercial Scout API should introduce explicit versioning, authentication, tenant isolation, compatibility policy, customer-safe telemetry, and a documented deprecation process before third parties are told to depend on these internal shapes.

Current itemStatusImplication
/api/chatApplication routeReal primary interface, but payload metadata may evolve with ProjectHub.
/api/thinkStale documentationOlder docs reference it; current server source reviewed here does not expose it.
/api/statsStale documentationOlder docs reference it; current server source reviewed here does not expose it.
Learning telemetry fieldsCompatibility stubFields can remain well-formed while background Think Mode itself is removed.
Browser-local endpointsExperimentalDo not treat as the normal production generation contract.
17 / Examples

Copyable requests.

Clear one session

POST /api/chat
curl -sS http://127.0.0.1:3000/api/chat \
  -H 'Content-Type: application/json' \
  -d '{"action":"clear","sessionId":"example-tab-1"}'

Detailed runtime health

GET /health
curl -sS http://127.0.0.1:3000/health

Contextual retrieval diagnostic

GET /api/retrieve
HISTORY='[{"user":"Tell me about ProjectHub","assistant":"..."}]'
curl -sS --get http://127.0.0.1:3000/api/retrieve \
  --data-urlencode 'q=what technology does it use?' \
  --data-urlencode "h=$HISTORY"

Prepare a browser-local packet

POST /api/client-packet
curl -sS http://127.0.0.1:3000/api/client-packet \
  -H 'Content-Type: application/json' \
  -d '{"message":"Does he know AWS?","sessionId":"local-demo"}'
18 / Source map

Where each contract comes from.

ConcernPrimary sourceWhat to verify
HTTP routes and payloadsserver-gemini.jsRoute existence, status behavior, request bounds, response construction, telemetry.
Production provider/model factsdata/scout-runtime-knowledge.jsonCloudflare model, rate/allocation controls, telemetry meaning.
Inference routinglib/local-model-router.jsProvider selection, Ollama gating, timeout propagation.
Cloudflare adapterlib/cloudflare-provider.jsCredentials, request shape, free-allocation errors, neuron estimation.
RAG primary pathlib/rag-agent.jsEvidence construction, tool enrichment, generation, repair, accepted outcome.
Validationlib/grounding-validator.jsEntity/number/relationship/provenance/polarity/claim checks.
Read-only toolslib/agent-tools.jsTool names, schemas, evidence-only behavior.
Release environmentsPROJECTHUB-DEVELOPMENT-AND-RELEASE-SPEC.mdProduction/staging source and deployment sequence.