Spectron has two configuration surfaces: server-wide settings (in the server binary or environment) and per-Context configuration (stored in the control plane and patchable at runtime).
Server-wide configuration
Server configuration is provided via environment variables or a TOML configuration file passed at startup. These settings apply to all Contexts unless overridden at the Context level.
Core settings
| Variable | Type | Default | Description |
|---|---|---|---|
SPECTRON_BIND | string | 0.0.0.0:8080 | Listen address and port |
SPECTRON_SURREALDB_URL | string | – | SurrealDB connection URL (required) |
SPECTRON_SURREALDB_USER | string | – | SurrealDB username (required) |
SPECTRON_SURREALDB_PASS | string | – | SurrealDB password (required) |
SPECTRON_OBJECT_STORE | string | local://./data | Object store backend (see below) |
Default model settings
These apply to all Contexts that do not override them:
| Variable | Default | Description |
|---|---|---|
SPECTRON_MODEL_EXTRACTION | gpt-4o-mini | LLM for experiential memory extraction (Stage 1 fast pass) |
SPECTRON_MODEL_EXTRACTION_STRONG | gpt-4o | LLM for extraction Stage 2 |
SPECTRON_MODEL_QUERY_UNDERSTANDING | gpt-4o-mini | LLM for query classification |
SPECTRON_MODEL_RESPONSE | gpt-4o-mini | LLM for response synthesis |
SPECTRON_MODEL_REFLECTION | gpt-4o | LLM for reflection operations |
SPECTRON_MODEL_BACKGROUND | gpt-4o-mini | LLM for background reconciliation |
SPECTRON_MODEL_EMBEDDING | text-embedding-3-small | Embedding model for the deployment (1536-dim in this release) |
The embedding model is fixed per deployment for launch — it is not a per-Context override. Context config rejects any models.embedding value other than the deployment default. Changing the server embedding model requires a reindex so vectors and HNSW indexes stay in the same embedding space.
Reranker (optional)
Cross-encoder reranking for /documents/query when use_reranker=true:
| Variable | Description |
|---|---|
SPECTRON_RERANKER_URL | POST endpoint for the reranker service. Unset ⇒ no provider; requests fall through to bi-encoder ordering. |
SPECTRON_RERANKER_MODEL | Required when URL is set. Boot error if URL is set without a model. |
SPECTRON_RERANKER_API_KEY | Optional bearer token (Authorization: Bearer …). |
Multimodal providers (optional)
HTTP OCR, CLIP, and speech-to-text for document ingestion (read by the worker role). An HTTP provider takes precedence over the built-in local fallback for the same modality. Misconfigured URLs fail at boot.
| Variable | Description |
|---|---|
SPECTRON_OCR_URL | POST endpoint for OCR. Unset ⇒ built-in or local Tesseract (when enabled). |
SPECTRON_OCR_MODEL | Required when OCR URL is set. |
SPECTRON_OCR_API_KEY | Optional bearer token. |
SPECTRON_CLIP_URL | POST endpoint for visual embeddings. CLIP output must match the 512-dim image_chunk width. |
SPECTRON_CLIP_MODEL | Required when CLIP URL is set. |
SPECTRON_CLIP_API_KEY | Optional bearer token. |
SPECTRON_STT_URL | POST endpoint for speech-to-text. |
SPECTRON_STT_MODEL | Required when STT URL is set. |
SPECTRON_STT_API_KEY | Optional bearer token. |
See Multimodal content.
Default provider API keys
| Variable | Description |
|---|---|
SPECTRON_OPENAI_API_KEY | Default OpenAI API key for all Contexts |
SPECTRON_ANTHROPIC_API_KEY | Default Anthropic API key for all Contexts |
Object store configuration
| Backend | SPECTRON_OBJECT_STORE format | Notes |
|---|---|---|
| Local filesystem | local:///path/to/data | Development and single-node deployments |
| Amazon S3 | s3://bucket-name/prefix | Requires AWS_ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEY or instance role |
| Google Cloud Storage | gcs://bucket-name/prefix | Requires GOOGLE_APPLICATION_CREDENTIALS |
| Azure Blob Storage | azure://container/prefix | Requires AZURE_STORAGE_ACCOUNT + AZURE_STORAGE_ACCESS_KEY |
CORS (browser clients)
Cross-origin browser calls to the API are off by default. Enable an origin allowlist when a web client (for example Surrealist against a Cloud-brokered access token) calls the user API from a different origin than the API host.
| Service | Variable | CLI flag |
|---|---|---|
| User API | SPECTRON_CORS_ALLOWED_ORIGINS | --cors-allowed-origins |
| Management API | SPECTRON_MANAGEMENT_CORS_ALLOWED_ORIGINS | --cors-allowed-origins |
Comma-separated origins. Entries are trimmed, lower-cased, and normalised (trailing / stripped). Exact entries match the Origin header verbatim; entries containing * are anchored globs on both sides (bare * or https://* are rejected). Allowed origins are echoed in Access-Control-Allow-Origin; credentials are not used — callers authenticate with Authorization, not cookies. Preflight mirrors request headers so SDK headers (api-version, X-Spectron-Context, Idempotency-Key, and others) pass without a fixed allowlist.
The management API is normally server-side only; CORS is optional there for operator tooling.
Per-Context configuration
Each Context stores a config object in the control plane. This is updated via PATCH /api/v1/contexts/{id} and applies immediately to new requests.
Full config schema
{
"config": {
"token_limit": 1000000,
"retention_days": 90,
"models": {
"extraction": "openai/gpt-4o-mini",
"extraction_strong": "openai/gpt-4o",
"query_understanding": "openai/gpt-4o-mini",
"response": "openai/gpt-4o-mini",
"reflection": "openai/gpt-4o",
"background": "openai/gpt-4o-mini"
},
"providers": {
"openai": "sk-...",
"anthropic": "sk-ant-..."
}
}
}Config fields
| Field | Type | Description |
|---|---|---|
token_limit | integer (optional) | Soft monthly token cap for metering and billing. Does not reject requests while enforcement_blocked is false. null = no cap. |
retention_days | integer (optional) | Automatic expiry for context-category experiential memory data. null = no automatic expiry. |
ingestion_profile | string | Document ingest dial: TextOnly, TextPlusKeyword, StandardMultimodal, or MultimodalFull (default). See Multimodal content. |
models.extraction | string | Model for Stage 1 fast extraction. Format: provider/model-name. |
models.extraction_strong | string | Model for Stage 2 strong extraction. |
models.query_understanding | string | Model for classifying and expanding queries. |
models.response | string | Model for synthesising formatted context responses. |
models.reflection | string | Model for reflection operations (reflect endpoint). |
models.background | string | Model for background reconciliation and cross-layer linking. |
providers.openai | string | OpenAI API key for this Context. Overrides the server-wide default. |
providers.anthropic | string | Anthropic API key for this Context. |
Provider API key visibility
Provider API keys are write-only on the API surface. The read projection for a Context replaces the key values with a providers_configured summary — names of providers for which this Context stores its own key:
{
"config": {
"providers_configured": ["openai", "anthropic"]
}
}This is not the same as GET /api/v1/{context_id}/providers, which lists providers reachable via a global deployment key or a per-Context key and includes selectable model ids. The two surfaces are not derivable from each other.
The raw key values never appear in read responses.
Top-level Context fields (outside config)
These fields live on the Context record itself, not inside the config object. A PATCH that only updates config cannot change them.
| Field | Type | Default | Description |
|---|---|---|---|
enforcement_blocked | boolean | false | When true, gated LLM-backed requests return 429 regardless of the soft token_limit. When false, usage may exceed token_limit (pay-as-you-go). |
See Cost and rate limits.
Patching config
Send only the fields you want to change. Unset fields are left unchanged (deep merge):
PATCH /api/v1/contexts/acme-prod
Content-Type: application/json
Authorization: Bearer mgmt-...
{
"config": {
"token_limit": 2000000,
"models": {
"reflection": "anthropic/claude-opus-4-7"
}
}
}Extraction tuning
Additional per-Context settings control extraction behaviour:
| Field | Type | Default | Description |
|---|---|---|---|
extraction.stage1_threshold | float | 0.7 | Confidence threshold below which Stage 2 runs |
extraction.max_entities_per_turn | integer | 20 | Maximum entities extracted per turn |
extraction.ontology_strict | boolean | false | Reject entities/attributes not in the ontology |
Cache settings
| Field | Type | Default | Description |
|---|---|---|---|
cache.semantic_ttl_seconds | integer | 3600 | TTL for semantic response cache entries |
cache.semantic_threshold | float | 0.95 | Cosine similarity threshold for cache hits |
Rate limiting
| Field | Type | Default | Description |
|---|---|---|---|
rate_limit.requests_per_minute | integer | 600 | Maximum requests per minute per Context |
rate_limit.tokens_per_minute | integer | 100000 | Maximum tokens per minute per Context (LLM calls) |
Key policy
| Field | Type | Default | Description |
|---|---|---|---|
allow_self_service_keys | boolean | true | When false, members cannot mint keys via POST /{ctx}/keys; use Cloud-brokered access tokens only. |
max_token_ttl_seconds | integer (optional) | none | Maximum TTL clamp applied to every key mint (management, broker, self-service). null = no clamp. |
Every data-plane API key must be bound to a principal. Keys with no principal binding are rejected with 401 — there is no unscoped passthrough mode. Mint keys under a principal (management API or self-service POST /{ctx}/keys).
Request and list limits
Operator-tunable ceilings (env vars, read at process start):
| Variable | Default | Caps |
|---|---|---|
SPECTRON_DEFAULT_PAGE_SIZE | 100 | Default limit when listing session turns and omitted elsewhere |
SPECTRON_MAX_LIST_LIMIT | 500 | Maximum rows per list response (list_turns, traces, audit) |
SPECTRON_MAX_QUERY_K | 50 | Maximum limit / k on /query, /context, document query, and MCP recall / context. Clamp-down only — the env var can lower the ceiling but never raise it above 50. Default answer size k / limit is 10. |
SPECTRON_RETRIEVAL_POOL_SIZE | 256 | Internal candidate-pool breadth for fused retrieval. Decoupled from k — k only truncates the fused answer; raising k does not widen the search pool. |
SPECTRON_RETRIEVAL_SECTION_EXPANSION | true | When on (default), pull same-section sibling passages into contextHits after ranking so synthesis sees section bodies, not only heading/pointer chunks. Opt out with 0 / false. Does not change ranked hits. See Section expansion. |
SPECTRON_DB_WS_MAX_MESSAGE_BYTES | 134217728 (128 MiB) | Client-side WebSocket per-message cap for pooled SurrealDB connections. Raise in lockstep with the server's SURREAL_WEBSOCKET_MAX_MESSAGE_SIZE when large document persists fail with Message too long. |
SPECTRON_TRACE_FEATURE_TTL_SECS | 60 | TTL (seconds) for the in-process per-(Context, scope) trace-features cache in the fused ranker — how long prior retrieval outcomes re-weight candidates before recomputation. Process-local; 0 or invalid values fall back to the default. |
Requests above the query ceiling return 400 Bad Request.
Reconciliation
| Field | Type | Default | Description |
|---|---|---|---|
reconciliation.confidence_floor | float | 0.7 | Minimum confidence required for same-provenance supersession |
Defaults reference
When a per-Context field is not set, the server-wide default applies. The effective configuration for a Context is always visible at:
GET /api/v1/contexts/{id}The response includes the config object with all effective values merged – Context-level overrides where set, server-wide defaults elsewhere.