Thought Cove

Developer Documentation

The Thought Cove API

A REST API for ingesting institutional documents into AI-ready Data Ponds, running grounded retrieval over them, and exporting portable knowledge packages — wire it into your SIS, ERP, or internal tools.

Quickstart

Every request goes to the API gateway and carries a Firebase ID token as a bearer credential. The base URL for your environment is:

https://fln-api-1082787657063.us-central1.run.app

A first authenticated call — resolve your tenant identity:

curl https://fln-api-1082787657063.us-central1.run.app/api/v1/tenant/whoami \
  -H "Authorization: Bearer $ID_TOKEN"

# => { "tenant_id": "0f8c...uuid", "email": "you@institution.edu" }

Your tenant_id is derived from your authenticated identity by the server — you never pass it in the body, and you can only ever read or write your own institution's data.

Authentication

Authentication is a Firebase ID token passed as Authorization: Bearer <token> on every request. Tokens are short-lived; refresh them through the Firebase client SDK.

  • One tenant per account. The server maps your verified identity to a single canonical tenant UUID and scopes every query to it via row-level security.
  • Open registration. Any verified account can provision a tenant; new tenants simply start with no billing credits until checkout.
  • No tenant spoofing. Endpoints ignore any tenant id in the request body and trust only the token.
Authorization: Bearer <firebase_id_token>
Content-Type: application/json

Endpoint Reference

The most-used endpoints are below. The full, always-current contract — request/response schemas included — lives in the interactive explorer.

MethodPathDescription
GET/api/v1/tenant/whoamiResolve your canonical tenant UUID and email.
GET/api/v1/tenant/meFetch your provisioned tenant profile (404 if not onboarded).
POST/api/v1/ingest/uploadMultipart upload of a document; starts ingestion in the background.
POST/api/v1/ingest/trigger-cloudTrigger ingestion for a file already in cloud storage (large files).
GET/api/v1/documentsList ingested documents and their processing status.
DELETE/api/v1/documents/{id}Delete a document and its derived chunks.
POST/api/v1/queryRun grounded retrieval (RAG) over selected documents.
POST/api/v1/documents/recommendRecommend relevant documents for a described project.
POST/api/v1/export/parquetExport a whole document-type + version as a Parquet + manifest knowledge package.
POST/api/v1/export/packageBundle an explicitly selected set of documents into one knowledge package.

Ingesting Documents

Two paths land documents in the pipeline:

  • Direct multipart (/api/v1/ingest/upload) — best for smaller files; the file streams through the gateway.
  • Cloud-first (/api/v1/ingest/trigger-cloud) — upload to cloud storage first (resumable), then trigger. This is the path for large files, up to 2GB per document.

Supported formats: PDF, DOCX, XLSX, CSV, TXT, MD. Ingestion is asynchronous — parsing, vision layout analysis, semantic chunking, and embedding run server-side. Poll status with GET /api/v1/documents; the requester is also emailed when a document is ready.

curl -X POST https://fln-api-1082787657063.us-central1.run.app/api/v1/ingest/upload \
  -H "Authorization: Bearer $ID_TOKEN" \
  -F "file=@catalog_2025.pdf" \
  -F "document_type=academic_catalog" \
  -F "version=2025" \
  -F "title=2025-26 Academic Catalog"

# => { "status": "success", "document_id": "...", "filename": "catalog_2025.pdf" }

Querying (RAG)

Retrieval is grounded: the engine embeds your question, runs vector similarity over the selected documents, and synthesizes an answer that cites sources inline as [1] [2]. If the answer isn't in the selected documents, it says so rather than guessing.

curl -X POST https://fln-api-1082787657063.us-central1.run.app/api/v1/query \
  -H "Authorization: Bearer $ID_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "What is the academic probation policy?",
    "document_ids": ["<doc-uuid>"],
    "mode": "hard_rag"
  }'

# => { "answer": "Students are placed on probation when ... [1]",
#      "references": [ { "document_id": "...", "page_number": 42, ... } ] }

Exporting Data (Portable Knowledge Packages)

You own your data and can export it at any time. An export is an Apache Parquet file plus a manifest.json describing the schema, embedding model, and a content hash — a portable, vendor-neutral package any downstream tool can load.

Export a whole document-type + version:

curl -X POST "https://fln-api-1082787657063.us-central1.run.app/api/v1/export/parquet?domain_id=academic_catalog&version=2025" \
  -H "Authorization: Bearer $ID_TOKEN" \
  -o knowledge_package.zip

Or bundle an explicit selection of documents — one, several, or all of them — into a single package:

curl -X POST "https://fln-api-1082787657063.us-central1.run.app/api/v1/export/package" \
  -H "Authorization: Bearer $ID_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "document_ids": ["<doc-uuid-1>", "<doc-uuid-2>"], "package_name": "hlc_evidence" }' \
  -o hlc_evidence.zip

A selection package's manifest.json carries "selection": true plus the exact document_ids and document_count it contains; domain_id/version collapse to the shared value or "mixed".

Billing & Credits

Ingestion is metered in normalized pages. A "page" is a billing unit standardized across formats, so a credit means the same amount of work whatever you upload:

FormatOne "page" =
PDF1 actual page (tables & images on it are included free)
Word (DOCX)~300 words
Excel / CSV~50 rows
Text / Markdown~2,000 characters

So a 40-page PDF costs 40 pages, while a 5,000-row spreadsheet costs about 100. A PDF is always billed by its page count — tables inside it never switch it to the spreadsheet rate. Credits are reserved before each ingestion run and refunded automatically if the pipeline fails. You can see your current balance any time on the Billing panel in your dashboard.

Limits & Errors

  • File size: up to 2GB per document (large files must use the cloud-first ingestion path).
  • Rate limits: ingestion is throttled to protect against runaway vision-parsing cost; retrieval queries are throttled to bound token usage. Expect HTTP 429 if you exceed them — back off and retry.
  • Common status codes: 401 invalid/expired token · 403 forbidden · 404 tenant not yet onboarded · 413 file exceeds the size limit · 402/insufficient credits on ingestion.

Need help? Email support@pryor-consulting.com.