Skip to content
SearchJet
Updated October 1, 2026

REST API Reference

SearchJet is a REST API that any HTTP client can call, with no client library to install. This page covers search and indexing in full and summarises the other endpoints. For a quick list, see the API Endpoints Reference.

Base URL and headers

https://app.searchjetengine.com/api/v1
Header When Value
Authorization Always Bearer YOUR_PUBLIC_KEY or Bearer YOUR_PRIVATE_KEY (see below)
Accept Always application/json. Without it, some errors come back as an HTML page or a redirect instead of JSON.
Content-Type Requests with a body application/json
X-Session-Id Optional, on search Your own session identifier, stored with search logs on paid plans

Keys go in the Authorization header and never in the query string.

Keys

Key Where to find it Accepted by
Public search key Dashboard, Sites list ("Public Key") GET /search, MCP, GET /client-info
Private key Dashboard, Sites → API Keys. It's 32 characters with no prefix, and it's shown only once. Indexing, analytics, click tracking, AI generation, GET /client-info

The wrong key type returns 401. Keep the private key on your server. See API Key Setup.

Uses the public key. CORS is enabled, so browsers can call this endpoint directly.

Parameters

Parameter Type Description
q string Required. The search query. If it's missing, you get 400 MISSING_QUERY.
limit integer 1 to 100, default 20.
page integer Default 1.
offset integer Default (page - 1) × limit. If you send both offset and page, offset wins.
filters string Meilisearch filter expression, at most 1,000 characters.
sort string Comma-separated attribute:asc or attribute:desc pairs, up to 5.
attributes string Comma-separated fields to return, limited to the fields your plan returns.
semantic boolean Hybrid semantic search. Requires Pro or higher, and semantic search enabled in the site settings.
semanticRatio float 0 to 1, default 0.5. Only used when semantic=true.
ai_answer boolean Generates an AI answer from the top results (all plans, within your monthly AI-answer quota).

On Pro, Growth and Enterprise you can also send facets, attributesToHighlight, attributesToCrop, cropLength, highlightPreTag, highlightPostTag, showMatchesPosition (adds _matchesPosition) and matchingStrategy. On Free they're ignored.

Free plan limits: you can filter only on id, title, type, price, currency and sku, and sort on one of id, title or price. On paid plans, you can filter and sort on any attribute marked filterable or sortable in Index Settings – General Attributes.

Response

Field Description
results The array of hits, in ranked order
remaining_quota Searches left this month (null if unlimited, -1 if metering is unavailable)
total Estimated number of matches
limit, offset, page Pagination applied (page = floor(offset / limit) + 1)
semantic_search_used Whether hybrid semantic search ran
facet_distribution, facet_stats Facet data (empty unless you requested facets)
processing_time_ms Engine processing time
answer With ai_answer=true and results: a string, or null if generation failed
semantic_ratio Only on semantic searches
meta Optional, e.g. {"warnings": ["AI answer quota exceeded."]}

Hit fields depend on your plan:

Plan Fields returned
Free id, title, url, type, thumbnail, price, currency, sku (no content or excerpt)
Pro The Free fields plus excerpt, content, author, date, image, categories, tags, regular_price, sale_price, stock_status
Growth, Enterprise All stored fields

On Free, a hit's id is returned as site__. Hits include _formatted only when a paid-plan request sets attributesToHighlight or attributesToCrop.

Example

curl -G "https://app.searchjetengine.com/api/v1/search" \
  -H "Authorization: Bearer $SEARCHJET_PUBLIC_KEY" \
  -H "Accept: application/json" \
  --data-urlencode "q=react tutorial" \
  --data-urlencode "limit=10" \
  --data-urlencode 'filters=type = "post"'

For a full response example, see the Search API Deep Dive.

POST /index/bulk and PATCH /index/bulk

Uses the private key, from server-side code only.

  • POST adds documents, and replaces any existing document with the same id.
  • PATCH merges the fields you send into existing documents.
Body field Description
documents Required. Up to 1,000 documents per request on Free, or 5,000 on paid plans. Each document can be at most 1 MB.
full_reindex Optional true: clears your existing documents before adding these. Counts against your daily reindex limit.

Each document needs an id (letters, digits, - and _) plus at least one other non-empty field. Common fields are title, content, url, excerpt and type (default page). The Index Management API lists the rest.

Indexing is asynchronous. The response is the queued task:

{"taskUid": 1234, "indexUid": "...", "status": "enqueued", "type": "documentAdditionOrUpdate", "enqueuedAt": "...", "message": "Indexed 2 documents. Total indexed: 120.", "was_cleared": false, "task_uid": 1234}

To check whether the task finished, poll GET /index/tasks/{taskUid}. Index requests are rejected with 429 quota_exceeded if they would take you past your plan's page limit. Near that limit, re-sent ids are counted as new documents. On Free and Pro, sending more than 1,000 documents a minute triggers abuse detection, so keep batches to 1,000 or fewer and space them out.

Other endpoints

Endpoint Key Body / params Response
DELETE /index/delete Private {"id": "..."} or {"ids": [...]} (max 500) {success, task_uid, status}
POST /index/delete-batch Private {"ids": [...]} or {"filter": "..."} {success, taskUid, deletedCount, message}
GET /index/tasks/{taskUid} Private – {success, task: {uid, status, type, details, error, duration, enqueued_at, started_at, finished_at}}
GET /index/count Private – {success, total_indexed_documents}
GET /index/{id} Private – {success, document}, or 404 not_found
GET /search-analytics Private days (1 to 90, default 30) {top_queries, zero_result_queries, total_searches, search_volume_by_day}
POST /search-analytics Private One log {query, results_count, ...} or {"logs": [...]} (max 100) {"status": "ok"}
POST /analytics/click Private document_id and position (both required), plus search_log_id, session_id, user_agent {"status": "ok"}
POST /ai/generate Private prompt (required, max 1,000 characters) {success, message, task_id, status: "pending"}
GET /ai/status/{id} Private – {success, status: "pending" | "complete" | "failed", output}
GET /client-info Public or private – {success, site_id, is_shared_index, plan, public_key, usage_limits}
POST /mcp/{publicKey} Public key in the path JSON-RPC 2.0 (Pro and above) MCP search tool

Analytics and click tracking need the private key. Call them from your own server, never from the browser.

Errors

Error bodies vary by endpoint. Search uses {"error", "code"}, the index endpoints use {"success": false, "error", "message"}, and the middleware uses {"message"} or {"error", "message"}. Error Handling lists every error, with retry code. Rate limits are covered in Rate Limits & Quotas.

Was this article helpful?

Ready to add search to your project?

Start free. No credit card required. Deploy in under 10 minutes.