Search and CMS integrations
Point the search calls you already make at DocSlurp. Get cited passages back.
Keep your search UI and swap the engine underneath. Point existing Algolia, Pagefind, Meilisearch or Typesense calls at DocSlurp and get cited passages from PDFs, Office files and media without rewriting the interface. Or add a search box to Astro, Next.js, WordPress or any HTML page.
Keep your search client
Algolia
PfPagefind
Meilisearch
Typesense
Pricing FAQ
Annual plans are billed up front.
Refunds are prorated for the unused months.
Seats can be added at any time.
8
Your workspace
Ship it on your site
Astro
Next.js
WordPress
</>Plain HTML
On this page
Already on a search service?
Adding search to a site?
How it works
- Your search interfaceInstantSearch, a Pagefind renderer, a custom box. Unchanged.
- Compatibility adapterSpeaks the original client’s request and response shapes.
- DocSlurp retrievalHybrid search across every extracted page, with citations and usage.
What changes
The client constructor and key. Index or collection names become a DocSlurp workspace: a slug like product-docs, a UUID, or default.
What stays
Your markup, routing, keyboard behavior and hit rendering. Response envelopes keep familiar fields such as hits, found and data().
What’s not emulated
Indexing, settings and admin APIs, ranking rules, analytics and static index files. Content goes in through native ingestion, and results are passages rather than whole pages.
Before you start
Create a browser key
On API keys, create a browser key with the search scope and add your site to its allowed websites.
Upload and wait
Upload your content with the SDK, CLI or HTTP API and wait for the run to finish. Adapters only search; they can’t upload.
Swap the client
Replace one constructor. Keep the rest of your search code, then run the go-live checklist.
import { createDocSlurpClient } from '@docslurp/sdk';
// Server-side only: DOCSLURP_API_KEY is a server key with the ingest scope.
const client = createDocSlurpClient();
const accepted = await client.upload({
urls: ['https://example.com/docs/install', 'https://example.com/docs/billing'],
workspaceId: 'product-docs', // omit to use your organization's default workspace
});
await client.waitForRun(accepted.run.id, { timeoutMs: 600_000 });# Upload local files and wait for indexing to finish.
docslurp upload ./site-export/*.pdf --workspace product-docs --watch
# Check that search returns results before you switch traffic.
docslurp search 'how do I install' --workspace product-docs --jsonRe-ingesting a source with the same canonicalId replaces it without a search gap. See the SDK reference for uploads, URL ingestion and replacements.
Compatibility matrix
Unsupported options fail loudly with HTTP 400 instead of being silently dropped, so a filter you rely on can never quietly disappear.
| Capability | Algolia | Pagefind | Meilisearch | Typesense |
|---|---|---|---|---|
| Keyword query | Supportedquery | Supportedsearch(term) | Supportedq | Supportedq + query_by |
| Pagination | Supportedpage, hitsPerPage | Supportedall results, lazy data() | Supportedoffset/limit, page | Supportedpage, per_page |
| Retrieval window | Supported≤ 1,000 hits | Partial100 passages | Partial100 passages | Partial100 passages |
| Batched queries | Supported≤ 10 requests | Not applicable— | Not supportedmulti-search | SupportedmultiSearch, ≤ 10 |
| Filters | Partialdocumented subset | Not supported400 | Not supported400 | Not supported400 |
| Facets | Partialwindow-scoped | Not supportedfilters() returns {} | Not supported400 | Not supportedfacet_counts: [] |
| Custom sort | Not supportedrelevance only | Not supported400 | Not supported400 | Not supported400 |
| Highlighting | Partialpre/post tags | Not supportedescaped excerpt | Not supported— | Not supported— |
| Index & settings APIs | Partialmigration helpers | Not supporteduse native ingest | Not supporteduse native ingest | Not supporteduse native ingest |
Keys and security
| Key | Prefix | Lives in | Use it for |
|---|---|---|---|
| Browser key search-only, allowed websites only | dslp_pub_ | Browser bundles, PUBLIC_* / NEXT_PUBLIC_* | Adapters, widget and Astro component on deliberately public content |
| Search-only server key | dslp_priv_ | Server secrets, WordPress options | Proxies: WordPress plugin, Next.js route handler |
| Server key with ingest | dslp_priv_ | CI or backend secret store | Uploads, URL ingestion and run waiting. Never in a browser or an agent prompt. |
The prefix makes a leaked key easy to spot and classify. Every SDK surface that can run in a browser throws before sending a dslp_priv_ key, and a key’s type can’t be changed after creation. Every adapter request keeps DocSlurp’s authorization, allowed-website checks, rate limits and usage accounting. Meilisearch and Pagefind use Authorization: Bearer; Typesense also accepts X-TYPESENSE-API-KEY and Algolia X-Algolia-API-Key. Responses are sent with Cache-Control: private, no-store.
Limits and errors
| Behavior | Contract |
|---|---|
| Retrieval window | Meilisearch, Typesense and Pagefind rank the first 100 passages per query. Pages that would reach past it return 400. docslurp.bounded, windowLimit and countIsExact: false mark every count as a window count. |
| Page size | Default 20 (Meilisearch, Typesense); Pagefind returns the whole window and loads data() lazily. |
| Batches | Up to 10 queries for Typesense multi-search and Algolia batches. |
| Empty query | Returns zero results without searching. It never lists the workspace’s contents. |
Wildcard * | Rejected. List documents with the native API. |
| Request size | Queries up to 16,000 characters; request bodies up to 64 KB. |
| SDK transport | 30-second deadline per request. Non-2xx responses throw with the status and body. |
| Ranking | DocSlurp hybrid retrieval with query expansion, reranking and other LLM-backed enhancements disabled, keeping adapter calls fast and inexpensive. |
HTTP/1.1 400 Bad Request
Content-Type: application/json
{
"code": "UNSUPPORTED_SEARCH_OPTION",
"error": "meilisearch: filter is not supported. Use the native search API for retrieval controls."
}400UNSUPPORTED_SEARCH_OPTION: an option outside the contract, or invalid JSON.401- Missing
Authorizationheader (or provider key header). 403- The key lacks the
searchscope, is invalid for this origin, or hit its rate limit. 404- The workspace doesn’t exist for this key’s organization.
Go-live checklist
Keep your old search entry point until every box is ticked. Start with one search box and one public workspace, migrate hit rendering first, then evaluate advanced features against the supported contract.
Troubleshooting
Cannot find module “@docslurp/sdk/search-adapters”
Your installed SDK is older than 0.2.0, which added these exports. Run npm install @docslurp/sdk@latest, then pin the version you test.
Algolia returns zero hits for every query
Batched Algolia requests return empty results for an index name that doesn’t match a workspace, rather than an error. Check the slug or UUID in the workspace settings, or use default.
Browser request fails with CORS or 403
Use a browser key with the search scope, add your site under allowed websites, and confirm the key’s organization owns the workspace. WordPress keeps its server key behind its proxy.
Results are empty right after upload
Upload is accepted before it is indexed. Wait for waitForRun() or docslurp upload --watch, check docslurp.availability, and remember that empty queries never return results.
HTTP 400 UNSUPPORTED_SEARCH_OPTION
The request used an option outside the supported contract: filters, facets, sort, wildcard *, a query_by other than text, or a page beyond the first 100 passages. Remove it or move that query to the native search API.
Source links are missing or wrong
Results carry a citation.documentId, not your site’s URL. Map document IDs to real public routes in resolveUrl. Pagefind rejects missing or unsafe URLs instead of guessing.
WordPress returns 429, 502 or 503
The proxy rate cap was hit, DocSlurp was unreachable, or plugin settings are incomplete. Check Settings > DocSlurp Search and your server logs, without logging the key.
Ranking differs from the old engine
DocSlurp ranks passages with its own hybrid retrieval. Compare representative queries and tune your content or the native retrieval controls; don’t expect identical order.
Examples
packages/sdk/examples/search-adapters.mjs runs every adapter against a real, already-indexed workspace. It sends four retrieval requests, which may incur embedding usage, so don’t wire it into an automatic smoke test.
pnpm --filter @docslurp/sdk build
DOCSLURP_API_KEY=… DOCSLURP_WORKSPACE_ID=product-docs \
node packages/sdk/examples/search-adapters.mjs "installation"Verify a local build before release
pnpm --filter @docslurp/sdk build
pnpm --filter @docslurp/contrib-search-compat build
pnpm --filter @docslurp/sdk test
node scripts/package-wordpress-search.mjs --check
pnpm --filter @docslurp/sdk pack --pack-destination /tmpThe packed SDK must include dist/search-adapters.js, its declarations, dist/search-widget.js and integrations/astro/DocSlurpSearch.astro. Release steps live in docs/releases.md; don’t assume a checkout change is already on npm.
Next steps
Adapters were checked against the official Algolia client, Pagefind API, Meilisearch search API and Typesense search API. The supported subsets above are DocSlurp’s contract; those services evolve independently.