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.appA 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/jsonEndpoint Reference
The most-used endpoints are below. The full, always-current contract — request/response schemas included — lives in the interactive explorer.
| Method | Path | Description |
|---|---|---|
| GET | /api/v1/tenant/whoami | Resolve your canonical tenant UUID and email. |
| GET | /api/v1/tenant/me | Fetch your provisioned tenant profile (404 if not onboarded). |
| POST | /api/v1/ingest/upload | Multipart upload of a document; starts ingestion in the background. |
| POST | /api/v1/ingest/trigger-cloud | Trigger ingestion for a file already in cloud storage (large files). |
| GET | /api/v1/documents | List ingested documents and their processing status. |
| DELETE | /api/v1/documents/{id} | Delete a document and its derived chunks. |
| POST | /api/v1/query | Run grounded retrieval (RAG) over selected documents. |
| POST | /api/v1/documents/recommend | Recommend relevant documents for a described project. |
| POST | /api/v1/export/parquet | Export a whole document-type + version as a Parquet + manifest knowledge package. |
| POST | /api/v1/export/package | Bundle 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.zipOr 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.zipA 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:
| Format | One "page" = |
|---|---|
| 1 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
429if you exceed them — back off and retry. - Common status codes:
401invalid/expired token ·403forbidden ·404tenant not yet onboarded ·413file exceeds the size limit ·402/insufficient creditson ingestion.
Need help? Email support@pryor-consulting.com.