BAMBOO

Overview

Live view of the RAVEN API service.

Application — probing
Welcome

What RAVEN does

RAVEN reads your documents and answers questions about them. You add files — PDFs, Word docs, Excel sheets, images, plain text — and RAVEN parses them, breaks them into passages, and indexes them so they're searchable by meaning. Your application then asks questions in plain English over HTTPS, and RAVEN replies with a written answer plus citations back to the exact source passages.

You don't run any AI models, manage a vector database, or pick an embedding service. RAVEN handles parsing, chunking, embedding, retrieval, reranking, and answer generation behind one API. Your app just makes authenticated HTTPS calls.

RAVEN is modular. You can use the whole pipeline (documents in, cited answers out) or just one piece — retrieval only, batch question-answering, structured table/key-value lookup, or document management. Pick what you need; ignore the rest. See Building blocks below.

About this console. The screen you're looking at is RAVEN's operator dashboard — for monitoring what's been ingested, retrying failed jobs, and inspecting the audit trail. Your application's end users never see this UI. The chat experience for your users lives inside your own application, talking to RAVEN over HTTPS. The Search Console tab here is for debugging — point it at a project, type a question, see what RAVEN would return.

Base URLs — production https://raven.cia.terabase.tools, staging https://raven-staging.cia.terabase.tools. The examples below use $RAVEN_HOST for the base URL and $RAVEN_KEY for your API key.

Integrate

Connecting your application

1 — Get a key and a namespace from an operator

Ask a RAVEN operator for an API key. You give them an application id (kebab-case, like traceline or marketing-tool) and one or more project ids. Each application_id + project_id pair forms a namespace — written application_id/project_id — which is the isolation boundary for your documents. The operator hands back one key scoped to your application's namespaces. Treat it like a password.

Throughout the API you can pass application_id + project_id as two fields, OR pass a single namespace string. They're equivalent — pick whichever is cleaner for your call site.

2 — Verify the key

curl "$RAVEN_HOST/v1/ready" \
  -H "X-API-Key: $RAVEN_KEY"
# → 200 {"status": "ready", "services": {...}}

3 — Add documents

Stage your files in an allow-listed S3 bucket, then ingest one by name:

curl -X POST "$RAVEN_HOST/v1/ingest/source" \
  -H "X-API-Key: $RAVEN_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "application_id": "myapp",
    "project_id": "q1-rfp",
    "source_uri": "s3://raven-sources-.../myapp/q1-rfp/contract.pdf"
  }'
# → 202 {"job_id": "...", "status": "queued", ...}

This returns immediately with a job id; indexing happens in the background (a few seconds for small text files, longer for large PDFs). Poll GET /v1/jobs/{job_id} for progress, or subscribe a webhook (step 5). To bulk-discover everything under a prefix, use POST /v1/ingest/source/prefix — note it only catalogs files; you then select which ones to index (see Building blocks → Ingestion).

4 — Ask questions

Let RAVEN write the answer with citations:

curl -X POST "$RAVEN_HOST/v1/chat" \
  -H "X-API-Key: $RAVEN_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "application_id": "myapp",
    "project_id": "q1-rfp",
    "question": "What is the warranty period?"
  }'
# → 200 {"answer": "...", "citations": [...], "answer_id": "..."}

Or get just the matching passages and run your own LLM:

curl -X POST "$RAVEN_HOST/v1/search" \
  -H "X-API-Key: $RAVEN_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "application_id": "myapp",
    "project_id": "q1-rfp",
    "query": "warranty period",
    "top_k": 5
  }'
# → 200 {"results": [...], "count": 5}

5 — (Optional) Receive webhooks

Instead of polling, have RAVEN POST you a signed event when an ingest job or async batch reaches a terminal state. Webhook registration is operator-managed (admin-only) — ask an operator to register your receiver URL and the events you want. See Building blocks → Webhooks for the signature scheme.

Adopt only the pieces you need. A search-only integration is steps 1–3 plus /v1/search. A full managed-chat integration adds /v1/chat. Webhooks, batch, streaming, and personas are all optional layers on top.
Building blocks

Capabilities you can pick from

Each row is a self-contained capability. Use one, several, or all of them.

CapabilityUse this when…Endpoint
Managed chat You want RAVEN to write the answer, with citations back to the source passages. POST /v1/chat
Retrieval only You already have your own LLM/agent and just want the matching passages. POST /v1/search
Batch chat You have many questions to answer in one round-trip (sync) or as a background job (async). POST /v1/chat/batch (up to 50)
Streaming answers You want tokens to appear as they're written for a live UX. POST /v1/chat with "stream": true
Structured lookup You need raw rows from indexed tables or extracted key/value forms. POST /v1/search/tables, POST /v1/search/key-values
Ingestion Add documents: a single S3 object, a batch of objects, or bulk-discover an S3 prefix into the catalog. POST /v1/ingest/source, /source/batch, /source/prefix
Catalog & selection You want to list discovered files, preview cost, then choose which to index. POST /v1/sources/catalog/upsert, /estimate, /select, /deselect
Personas & formats You want a custom system prompt, tool allowlist, or a fixed output shape (terse / JSON-schema). domain_knowledge_id + response_format on chat
Webhooks You want push notifications on ingest / answer-batch status instead of polling. operator-registered; events below
Audit trail You need to trace an answer back to its citations, or list events for a namespace. GET /v1/audit/answers, /v1/audit/answers/{id}, /v1/audit/events
Document & job inspection You want to see what's indexed, check ingest progress, or remove a document. GET /v1/documents, /v1/jobs, DELETE /v1/documents/{id}
Self-service namespace ops Your app manages its own namespace lifecycle (pause, resume, reindex, delete). /v1/admin/* scoped to your namespace

Batch chat — sync and async

Send up to 50 questions in one call. By default the call blocks and returns every answer inline. For large batches that would outlast your load balancer's idle timeout, set "async_": true (or add ?async=true): RAVEN returns 202 + a batch_id immediately, drains the batch in the background, and you poll GET /v1/answer/batch/{batch_id} (or subscribe a webhook).

curl -X POST "$RAVEN_HOST/v1/chat/batch" \
  -H "X-API-Key: $RAVEN_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "application_id": "myapp",
    "project_id": "q1-rfp",
    "questions": ["What is the warranty period?", "Who is the inverter vendor?"]
  }'

Streaming

Add "stream": true to a /v1/chat body. The response is text/event-stream (Server-Sent Events) carrying token / tool_call / tool_result / done frames as they happen. Auth and scope are still checked before the first byte, and the final frame still includes an answer_id for the audit trail.

Personas (Domain Knowledge) & response formats

Pass domain_knowledge_id on any /v1/chat or /v1/chat/batch call to apply a tenant-authored system prompt, tool allowlist, and default output format on top of RAVEN's safety rules. Pass response_format ({"style": "narrative" | "terse" | "json", "schema": {...}}) to pin the output shape for one call. An unknown or cross-tenant domain_knowledge_id returns 404 domain_knowledge_not_found; if omitted, your tenant+app default persona applies, else RAVEN's built-in prompt. Manage personas in the Personas tab or via /v1/domain-knowledges. Full design: docs/RAVEN-DOMAIN-KNOWLEDGE-DESIGN.md.

Webhooks

When a webhook is registered for your namespace, RAVEN POSTs a JSON event to your URL on terminal status. Each delivery carries two headers:

X-Raven-Signature: sha256=<hex HMAC-SHA256(secret, "{timestamp}." + body)>
X-Raven-Timestamp: <unix epoch seconds>

To verify: reject if X-Raven-Timestamp is more than ~5 minutes (300s) off your clock, recompute the HMAC over "{timestamp}." + rawBody with your webhook secret, and compare constant-time against the digest. Event type strings:

Event typeFires when
job.completeAn ingest job finished cleanly
job.copiesAn ingest job matched content already indexed in the namespace
job.partialAn ingest job indexed some pages but some page ranges failed
job.failed / job.dead_letteredAn ingest job failed terminally
answer_batch.complete / .partial / .failedAn async batch reached terminal status
document.deletedA document was removed from the index

The payload body is {"webhook_id": ..., "event": {"type": ..., "occurred_at": ..., "job": {...}}}. The job/batch summary is lean — fetch full detail via GET /v1/jobs/{id} or GET /v1/answer/batch/{id}.

Self-service namespace management

Your namespace-scoped key can manage its own namespace through a subset of the /v1/admin/* routes — no global admin key needed. Acting on a namespace your key doesn't cover returns 403 namespace_forbidden.

ActionEndpoint
Pause / resume ingest for a namespacePOST /v1/admin/tenants/{namespace}/pause · /resume
Reindex a documentPOST /v1/admin/documents/{id}/reindex
Cancel queued jobs in a namespacePOST /v1/admin/jobs/cancel?namespace=...
Delete a whole namespaceDELETE /v1/admin/namespaces/{namespace}

Destructive teardown (namespace / application delete) requires the header X-Confirm-Destroy: yes. Add ?delete_source_files=true to also remove S3 files from RAVEN-owned buckets, or ?purge_history=true for GDPR-style erasure of stored prompts. Webhook and API-key CRUD remain admin-only.

Conventions

Headers, errors & empty namespaces

Every request needs the X-API-Key header. Optionally add X-Actor-User-Id — an opaque label identifying which of your end users triggered the call. RAVEN never authorizes on it; it's stamped on the audit row for your own traceability.

Structured error envelope

Every 4xx/5xx response (published in the OpenAPI spec) comes back in one shape so you can codegen typed error handling:

{
  "error_code": "namespace_forbidden",   // machine-readable, snake_case
  "message": "tenant 'x' is not authorised for namespace 'y'",
  "retryable": false,                     // true → safe to retry
  "request_id": "req_...",                // mirrors X-Request-ID; share with operators
  "service": null,                        // upstream that caused it, when relevant
  "stage": null,                          // ingest stage, when relevant
  "details": null                         // curated, client-safe context
}

429 and 503 responses also carry a Retry-After header. Graceful degradation (e.g. a reranker fallback) is reported on a successful response via a top-level {"degraded": true, "warnings": [...]} envelope plus a Warning: 299 header — not an error.

Querying a namespace with nothing indexed yet

This is not an error. If you call /v1/search or /v1/chat (including streaming) against a namespace that has no indexed content yet, RAVEN returns 200 with an empty result set / a clean "no indexed content yet" answer and a namespace_not_indexed degradation warning — never a 503. That lets you distinguish "nothing ingested yet" from "indexed but no match" without special-casing a failure.

Common error codes

You seeWhat it meansFix
401 missing_api_keyNo X-API-Key headerAdd the header
401 invalid_api_keyKey not recognisedRe-check the value; ask an operator if it was rotated
403 namespace_forbiddenYour key doesn't cover this application_id/project_idConfirm the IDs match what the operator assigned
400 "source_uri must be an s3://…"You passed a non-S3 URI to ingestUse s3://bucket/key (the prefix endpoint also accepts AWS console / https S3 URLs)
403 "Source bucket … not allowed"The bucket isn't allow-listedStage the file in an allowed bucket, or ask an operator to add yours
403 catalog_selection_requiredStrict catalog mode is on for your tenantUse the catalog flow: /sources/catalog/upsert then /select
Job stuck in queuedWorker busy, paused, or not yet selected in the catalogCheck GET /v1/jobs/{job_id} for the current stage
404 domain_knowledge_not_foundUnknown or cross-tenant domain_knowledge_idList yours via GET /v1/domain-knowledges

Every error includes a request_id. Share it with an operator and they can grep the structured log for the full server-side trace.

Readiness
—
awaiting probe
Ingest jobs
0
in current scope
Documents
0
indexed
Audited answers
0
retained
Log

Recent activity

0 events
Loading activity…
Diagnostics

Service health

not probed
Click "Probe /v1/health" to run a full dependency check.
Pipeline

Ingest Jobs

0 loaded
No jobs loaded yet.
Manifest

Job detail

Select a job to see its events.
Corpus

Documents

0 loaded
No documents loaded yet.
BAMBOO

Document detail

Select a document to view its source objects.
Provenance Ledger

Every answer trails back to a chunk, page, and section. Validate citations · expose hallucinations · close the loop.

Answers 0 loaded in scope
Validated citations 0 source-backed
Unverified 0 needs review
Avg latency — answer generation
Trail

Audit Trail

Review answer provenance, citation health, and tool traces.

0 loaded
No audited answers loaded yet.
Exhibit

Answer detail

Select an answer to see citations.
Intake

Ingest

Stage new documents into the current application.

Upload files

Drop a folder or files, or use the buttons below. Each file is staged + queued individually.

idle

From S3 source URI

Ingest an already-staged object without re-uploading bytes.

idle

Populate source catalog (S3 prefix)

Paste one S3 folder URL — RAVEN lists matching objects and adds them to the source catalog (nothing is ingested until you select files). Accepts s3://bucket/prefix/ or an AWS Console URL.

idle
Log

Recent ingestions

0 loaded
Submit an ingest to see batch progress here.
Stuck jobs
—
running past lease expiry
Dead lettered
—
awaiting redrive
In flight
—
running across all tenants
Queued
—
awaiting workers
Operator

Operations console

Wedge

Stuck jobs

—
Admin probe pending…
Redrive

Dead-lettered jobs

—
Admin probe pending…
Ledger

Jobs by tenant

—
Admin probe pending…
Tenancy

Applications & projects

Scopes register automatically when your app calls ingest, chat, or search with a valid namespace. Delete removes documents, the vector index, catalog rows, and jobs for that project. Requires an admin API key and request header X-Confirm-Destroy: yes.

—
Save an API key and reload to list scopes.
Keys

API keys

—
Click "Reload" to fetch the current key inventory.
Hooks

Webhooks

—
Click "Reload" to fetch active webhook subscriptions.
Vectors

Vector indexes

—
Click "Reload" to inventory every namespace's vector index.
Deployment

Active features

Live snapshot of this backend task's feature flags and config values — figure vision, web enrichment, judge, chat, and answering. Read directly from process environment on every request; requires an admin API key.

—
Click "Reload" to fetch feature status.
Behavior

Personas (Domain Knowledge)

Personas are tenant-authored system prompts the chat agent uses on top of RAVEN’s built-in safety rules. Each call to /v1/chat or /v1/chat/batch can pass domain_knowledge_id; with no id, the default for the calling application is applied. This list shows all personas for your tenant (not only the current application filter).

—
Click "Reload" to list personas for your tenant.