Ingestion API
Ingest content directly into your search index without crawling. Ideal for CMS integrations, dynamic content, or bulk imports.
Ingest Pages
POST /api/sites/{siteId}/pages
Authorization: Bearer qs_your_api_key
Content-Type: application/json
{
"pages": [
{
"url": "https://example.com/docs/getting-started",
"title": "Getting Started Guide",
"content": "Welcome to our platform! This guide will help you get up and running...",
"metadata": { "section": "docs" }
}
]
}
Page Fields
| Field | Type | Required | Description |
|---|---|---|---|
url | string | Yes | Unique URL identifier for the page |
content | string | Yes | Full page content (plain text or HTML) |
title | string | No | Page title (auto-extracted if HTML) |
summary | string | No | Brief description for search results |
tags | string[] | No | Keywords for search relevance |
Response
{
"success": true,
"processed": 1,
"skipped": 0,
"failed": 0,
"results": [
{
"url": "https://example.com/docs/getting-started",
"status": "success",
"chunks": 1,
"isNew": true,
"processingTimeMs": 3514
}
]
}
Content Processing
When you ingest content:
- HTML is cleaned - Navigation, headers, footers are removed
- Metadata is extracted - Title, summary, tags (if not provided)
- Content is chunked - Split into searchable segments
- Embeddings are generated - For semantic search
Pre-processed Content
If you've already cleaned your content, you can skip AI processing by providing all metadata fields (title, summary, tags):
- HTML content → Always processed (to remove boilerplate)
- Plain text + all metadata → Indexed directly (faster, cheaper)
- Plain text, missing metadata → AI extracts missing fields
Batch Ingestion
Ingest up to 100 pages per request:
{
"pages": [
{ "url": "https://example.com/page1", "title": "Page 1", "content": "..." },
{ "url": "https://example.com/page2", "title": "Page 2", "content": "..." },
{ "url": "https://example.com/page3", "title": "Page 3", "content": "..." }
]
}
For large imports, batch your requests and implement retry logic for any errors.
Updating Content
To update a page, simply ingest it again with the same URL. The new content replaces the old.
Delete Content
Pass urls to remove specific pages. It takes an array, so one request can remove many pages — there is no need to call it per URL.
DELETE /api/sites/{siteId}/pages
Authorization: Bearer qs_your_api_key
Content-Type: application/json
{
"urls": ["https://example.com/docs/getting-started"]
}
Removes each page and all of its chunks from the index. URLs must match exactly, including the scheme and host, as they were ingested or crawled.
Delete by Pattern
Pass patterns instead to remove a whole section without listing every URL:
DELETE /api/sites/{siteId}/pages
Authorization: Bearer qs_your_api_key
Content-Type: application/json
{
"patterns": ["/blog/archive/*"]
}
At least one of urls, patterns or keys is required; you may combine them in a single request.
Response
{
"message": "Pages deleted successfully",
"siteId": "4226a896-f2d3-40d3-aa80-5bc627d4c83b",
"requestedUrls": 1,
"deletedChunks": 1,
"deletedPages": 1
}
deletedPages is what was actually removed, which can be lower thanrequestedUrls. Deleting a URL that is not in the index is not an error — it succeeds and removes nothing — so check deletedPagesrather than the status code if you need to know whether anything changed.
Ingested pages are not removed automatically
Stale-content reconciliation — which removes indexed pages once they disappear from your site — only covers pages the crawler found. A page pushed in through this API stays indexed until you delete it, even if the source page is later removed. If your CMS deletes content, call the delete endpoint as part of that workflow.
List Indexed Pages
To see what is currently in the index, for example to verify a delete:
GET /api/sites/{siteId}/index-pages?limit=50
Authorization: Bearer qs_your_api_key
Purge the Whole Index
POST /api/sites/{siteId}/purge empties the index for a site. This cannot be undone; the content must be re-crawled or re-ingested.
Use Cases
CMS Integration
Trigger ingestion when content is published:
- Listen for publish/update webhooks from your CMS
- Fetch the page content
- POST to the ingestion API
Bulk Import
Import existing content:
- Export content from your source system
- Transform into the required format
- Batch ingest in chunks of 100
- Monitor for errors and retry failures
Dynamic Content
For content that changes frequently:
- Ingest on a schedule (e.g., hourly)
- Or trigger on content changes
- Consider using tags to track content freshness
Limits
| Limit | Value |
|---|---|
| Pages per request | 100 |
| Content size per page | 1 MB |
| Requests per minute | 60 |