Index Management API
## Overview
The Index Management API lets you programmatically control your SearchJet search index. Add documents in bulk, remove outdated entries, trigger full reindex operations, and monitor index health and statistics.
All index endpoints require authentication via Bearer token and operate on a per-site basis.
---
## Index Status
Retrieve current index statistics including document count, last update time, and indexing status.
### Endpoint
```
GET /api/v1/sites/{siteId}/index
```
### Response
```json
{
"siteId": "site_abc123",
"status": "ready",
"documentCount": 15420,
"lastUpdatedAt": "2025-07-10T14:30:00Z",
"lastReindexAt": "2025-07-10T14:30:00Z",
"indexSizeBytes": 52428800,
"fields": [
"id",
"title",
"slug",
"content",
"category",
"published_at",
"price",
"tags"
]
}
```
### Status Values
| Status | Description |
|---|---|
| `ready` | Index is healthy and searchable |
| `indexing` | A reindex or bulk operation is in progress |
| `error` | An indexing error occurred — check logs |
| `empty` | No documents have been indexed |
---
## Add / Update Documents
Index one or more documents. If a document with the same `id` already exists, it is replaced entirely. This is an upsert operation.
### Endpoint
```
POST /api/v1/sites/{siteId}/index/documents
```
### Request Body
```json
{
"documents": [
{
"id": "doc_001",
"title": "Getting Started with SearchJet",
"slug": "getting-started-searchjet",
"content": "SearchJet is a powerful search engine...",
"category": "tutorials",
"tags": ["search", "tutorial", "beginner"],
"published_at": "2025-07-01T10:00:00Z",
"price": null,
"featured": true
},
{
"id": "doc_002",
"title": "Advanced Filtering Techniques",
"slug": "advanced-filtering",
"content": "Learn how to use filters effectively...",
"category": "tutorials",
"tags": ["search", "filtering", "advanced"],
"published_at": "2025-07-05T10:00:00Z",
"price": null,
"featured": false
}
]
}
```
### Response
```json
{
"indexed": 2,
"failed": 0,
"errors": []
}
```
### Limits
- Maximum **1,000 documents** per request
- Maximum **10 MB** request body size
- Document IDs must be unique strings (max 256 characters)
---
## Remove Documents
Delete documents from the index by providing an array of document IDs.
### Endpoint
```
DELETE /api/v1/sites/{siteId}/index/documents
```
### Request Body
```json
{
"ids": ["doc_001", "doc_002"]
}
```
### Response
```json
{
"deleted": 2,
"failed": 0,
"errors": []
}
```
---
## Full Reindex
Trigger a complete reindex of your site. This rebuilds the search index from your source data. Use this after schema changes or bulk data updates.
### Endpoint
```
POST /api/v1/sites/{siteId}/index/reindex
```
### Request Body (Optional)
```json
{
"strategy": "full",
"notify_webhook": true
}
```
| Parameter | Type | Default | Description |
|---|---|---|---|
| `strategy` | string | `full` | `full` replaces entire index; `incremental` processes only changes |
| `notify_webhook` | boolean | `true` | Send a webhook when reindex completes |
### Response
```json
{
"jobId": "reindex_job_xyz789",
"status": "queued",
"estimatedDurationSeconds": 120
}
```
Reindex operations run asynchronously. Poll the index status endpoint or wait for the completion webhook.
---
## Bulk Document Operations
Perform mixed add, update, and delete operations in a single request.
### Endpoint
```
POST /api/v1/index/bulk
```
### Request Body
```json
{
"operations": [
{
"action": "upsert",
"id": "doc_001",
"document": {
"title": "Updated Title",
"content": "Updated content..."
}
},
{
"action": "upsert",
"id": "doc_003",
"document": {
"title": "New Document",
"content": "Brand new content..."
}
},
{
"action": "delete",
"id": "doc_002"
}
]
}
```
### Action Types
| Action | Description |
|---|---|
| `upsert` | Create or replace a document |
| `delete` | Remove a document by ID |
### Response
```json
{
"processed": 3,
"succeeded": 3,
"failed": 0,
"errors": []
}
```
---
## Document Schema
Documents are schema-flexible. You can include any JSON fields. SearchJet automatically indexes all fields unless you configure field-specific settings.
### Recommended Fields
| Field | Type | Description |
|---|---|---|
| `id` | string | Unique document identifier (required) |
| `title` | string | Document title (heavily weighted in relevance) |
| `slug` | string | URL-friendly identifier |
| `content` | string | Full text content |
| `category` | string | Categorization field for filtering/faceting |
| `tags` | array | Array of string tags |
| `published_at` | string | ISO 8601 timestamp |
| `price` | number | Numeric field for range filters |
### Field Type Behavior
- **String fields** are tokenized and full-text searchable.
- **Numeric fields** support range comparisons (`>`, `<`, `>=`, `<=`).
- **Array fields** support `IN` and `NOT IN` filters.
- **Boolean fields** can be filtered with equality checks.
---
## Code Examples
### cURL — Add Documents
```bash
curl -X POST "https://app.searchjetengine.com/api/v1/sites/site_abc123/index/documents" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"documents": [
{
"id": "doc_001",
"title": "Hello World",
"content": "First document"
}
]
}'
```
### JavaScript (Fetch) — Trigger Reindex
```javascript
const reindex = async (siteId) => {
const response = await fetch(
`https://app.searchjetengine.com/api/v1/sites/${siteId}/index/reindex`,
{
method: "POST",
headers: {
Authorization: `Bearer ${process.env.SEARCHJET_API_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({ strategy: "full" })
}
);
return response.json();
};
const job = await reindex("site_abc123");
console.log(`Reindex job queued: ${job.jobId}`);
```
### Python (requests) — Check Index Status
```python
import requests
def get_index_status(site_id):
response = requests.get(
f"https://app.searchjetengine.com/api/v1/sites/{site_id}/index",
headers={"Authorization": "Bearer YOUR_API_KEY"}
)
return response.json()
status = get_index_status("site_abc123")
print(f"Documents indexed: {status['documentCount']}")
print(f"Status: {status['status']}")
```
### PHP (Guzzle) — Bulk Delete
```php
use GuzzleHttp\Client;
$client = new Client([
'base_uri' => 'https://app.searchjetengine.com',
'headers' => ['Authorization' => 'Bearer YOUR_API_KEY']
]);
$response = $client->delete('/api/v1/sites/site_abc123/index/documents', [
'json' => ['ids' => ['doc_001', 'doc_002', 'doc_003']]
]);
$data = json_decode($response->getBody(), true);
echo "Deleted {$data['deleted']} documents\n";
```
---
## Best Practices
- **Batch operations.** Send up to 1,000 documents per request rather than individual calls.
- **Use unique, stable IDs.** Document IDs should be consistent across updates to enable upsert behavior.
- **Monitor reindex jobs.** Poll the index status endpoint or set up a webhook to know when reindex completes.
- **Avoid simultaneous reindex operations.** Wait for one reindex to finish before starting another.
- **Schema validation.** Define expected fields in your application layer before sending to SearchJet.
- **Incremental updates.** Use the bulk API with upsert actions for ongoing updates instead of full reindex.
---
## Related Pages
- [Search API](/docs/search-api) — Query your indexed documents
- [Webhooks](/docs/webhooks) — Get notified when indexing completes
- [Error Handling](/docs/error-handling) — Handle API errors gracefully