Upload files, paste text, or sync from Notion and Google Drive into a Feather knowledge base. Track ingestion status and search your indexed content.
Feather’s knowledge base pipeline accepts documents from virtually any source — local files, raw text, and third-party platforms like Notion, Google Drive, and S3. Once ingested, documents are chunked, embedded, and indexed so your agents can perform semantic search at inference time. This guide covers the full ingestion lifecycle: uploading content, tracking job status, connecting external sources, and validating results with a live search query.
All file and text uploads go through a single unified endpoint that accepts multipart/form-data. You describe what you’re uploading with a JSON manifest and attach the actual file bytes separately.Endpoint:POST /v1/knowledge-base/knowledge-bases/{kb_id}/ingestThe request has two parts:
Field
Type
Description
manifest
JSON string
Array of item descriptors — one object per document
files
File parts
The actual file bytes, referenced by file_index in the manifest
Manifest item formats:
[ { "type": "text", "title": "FAQ", "content": "What is Feather? Feather is an AI-powered customer experience platform." }, { "type": "file", "file_index": 0, "title": "Product Guide" }]
Each item has a type of either text (inline content) or file (references an uploaded file part by its zero-based index). The title is stored with the document and surfaces in search results.Full example — uploading a file and a text snippet together:
curl -X POST https://api-sandbox.featherhq.com/v1/knowledge-base/knowledge-bases/kb_01hx4mno5pqrstuvwxyz0001/ingest \ -H "x-api-key: $FEATHER_API_KEY" \ -F 'manifest=[{"type":"text","title":"FAQ","content":"What is Feather? Feather is an AI-powered customer experience platform."},{"type":"file","file_index":0,"title":"Product Guide"}]' \ -F 'files=@./product-guide.pdf'
Each item in the response reports either queued (accepted for processing) or duplicate (an identical document already exists in the knowledge base and was skipped). Save the ingestion_job_id to track progress.
Duplicate detection is hash-based. If you re-upload the same file after editing it, the content hash changes and it will be ingested as a new version.
Ingestion is asynchronous. Documents move through a pipeline — queued → processing → completed (or failed). Poll the job endpoint until status reaches a terminal state.Poll a specific job:
The aggregate counts documents by lifecycle state: pending, processing, active (indexed and live), draft, archived, failed, and quarantined, with total summing them. Use this endpoint on the dashboard or during health checks to confirm your knowledge base is fully indexed — i.e. all documents are active — before going live.
Retry failed documents without re-uploading them. Send a POST to /v1/knowledge-base/ingestion-jobs/{job_id}/retry and Feather will re-queue only the failed items from that job.
For Notion pages, Google Drive folders, and S3 buckets, Feather syncs content automatically rather than requiring manual uploads. The flow is: create a connection → add the source → define roots → trigger a sync → optionally schedule recurring syncs.
External source integrations require an active integration connection for your provider. See Connect an Integration to set one up before continuing.
The example above syncs the source every hour (3600 seconds). Set auto_sync_enabled: false to pause automatic syncing without deleting the schedule configuration.
Before connecting a knowledge base to an agent, validate that your content is indexed and returning relevant results.
curl -X POST https://api-sandbox.featherhq.com/v1/knowledge-base/search \ -H "x-api-key: $FEATHER_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "query": "How do I reset my password?", "kb_ids": ["kb_01hx4mno5pqrstuvwxyz0001"], "limit": 5 }'
{ "results": [ { "chunk_id": "chk_01hx9chunk111111111aaaa", "kb_id": "kb_01hx4mno5pqrstuvwxyz0001", "document_id": "doc_01hx7pdf000000000000002", "document_title": "Product Guide", "source_type": "file", "content": "To reset your password, visit the login page and click 'Forgot password'. Enter your registered email address and follow the link sent to your inbox.", "score": 0.94, "chunk_index": 3 }, { "chunk_id": "chk_01hx9chunk222222222bbbb", "kb_id": "kb_01hx4mno5pqrstuvwxyz0001", "document_id": "doc_01hx7faq000000000000001", "document_title": "FAQ", "source_type": "text", "content": "Password resets expire after 30 minutes. If your link has expired, request a new one from the login page.", "score": 0.87, "chunk_index": 0 } ], "total_results": 2, "ranking_mode": "global_score", "answerability": { "label": "answerable", "reason_code": "above_high_threshold", "raw_top_score": 0.94, "score_basis": "raw_dotproduct" }}
Field
Description
total_results
Total candidate count before the flat results list is truncated by limit
ranking_mode
How results were ordered: global_score, reranked, or grouped_unranked
answerability
Object describing whether the knowledge base likely contains a sufficient answer. Its label is one of answerable, low_confidence, not_answerable, or unknown, alongside reason_code, raw_top_score, and score_basis. Present only when the answerability gate is enabled for your org; otherwise null
chunk_id
Unique ID of the retrieved text chunk
document_title
Title assigned during ingestion
content
The raw text of the chunk
score
Semantic similarity score (0–1). Higher is more relevant
A high score means the chunk is semantically similar to the query — not that it’s factually correct. Always review new knowledge bases manually before enabling them in production agents.