# AI Chat Click Source: https://docs.cludo.com/api-reference/ai-chat-click /openapi/ai.json post /api/v4/{customerId}/{engineId}/search/answer/click Track citation or URL clicks from AI Chat results. # AI Chat Feedback Source: https://docs.cludo.com/api-reference/ai-chat-feedback /openapi/ai.json post /api/v4/{customerId}/{engineId}/search/answer/feedback Submit thumbs-up/down style feedback for an AI chat exchange (`rating`: `positive` or `negative`), plus optional `reason`, `comment`, and `language`. # AI Summary Feedback Source: https://docs.cludo.com/api-reference/ai-summary-feedback /openapi/ai.json post /api/v4/{customerId}/{engineId}/search/summarize/feedback Submit feedback for an AI summary: `rating` (string), optional `reason` and `comment`. # Bulk Delete Source: https://docs.cludo.com/api-reference/bulk-delete /openapi/index-management.json post /api/v4/{customerId}/index/{crawlerId}/documents/bulk-delete Deletes documents matching a set of filter predicates. # Create Banner Source: https://docs.cludo.com/api-reference/create-banner /openapi/search-tools.json post /api/banners Creates a banner. The server assigns `id`. # Create or Replace Source: https://docs.cludo.com/api-reference/create-or-replace /openapi/index-management.json put /api/v4/{customerId}/index/{crawlerId}/documents Create new documents or fully replace existing ones in the index. Send a JSON array of document objects; each document must include an `id` and a `fields` object. Common field names include Title, Url, Description, Date, Category, and Language. # Create Quicklink Source: https://docs.cludo.com/api-reference/create-quicklink /openapi/search-tools.json post /api/quicklinks Creates a quicklink. The server assigns `id`. # Create Ranking Source: https://docs.cludo.com/api-reference/create-ranking /openapi/search-tools.json post /api/rankings Creates a ranking. The server assigns `id`. # Create Synonym Group Source: https://docs.cludo.com/api-reference/create-synonym-group /openapi/search-tools.json post /api/synonymsgroup Creates a synonym group. # Delete Banner Source: https://docs.cludo.com/api-reference/delete-banner /openapi/search-tools.json delete /api/banners/{bannerId} Deletes a banner by ID. # Delete Quicklink Source: https://docs.cludo.com/api-reference/delete-quicklink /openapi/search-tools.json delete /api/quicklinks/{quicklinkId} Deletes a quicklink by ID. # Delete Ranking Source: https://docs.cludo.com/api-reference/delete-ranking /openapi/search-tools.json delete /api/rankings/{rankingId} Deletes a ranking by ID. # Delete Synonym Group Source: https://docs.cludo.com/api-reference/delete-synonym-group /openapi/search-tools.json delete /api/synonymsgroup Deletes synonym groups. Pass comma-separated IDs in `groupIds`. # Get Quicklink Source: https://docs.cludo.com/api-reference/get-quicklink /openapi/search-tools.json get /api/quicklinks/{quicklinkId} Returns one quicklink by ID. # Get Quicklinks by Terms Source: https://docs.cludo.com/api-reference/get-quicklinks-by-terms /openapi/search-tools.json get /api/engine/{engineId}/quicklinkterms Returns quicklinks whose trigger terms match `searchword` for the given engine. # Get Single Banner Source: https://docs.cludo.com/api-reference/get-single-banner /openapi/search-tools.json get /api/banners/{bannerId} Returns one banner by ID. # Get Single Ranking Source: https://docs.cludo.com/api-reference/get-single-ranking /openapi/search-tools.json get /api/rankings/{rankingId} Returns one ranking by ID. # Get Synonyms by Language or Synonym Group Source: https://docs.cludo.com/api-reference/get-synonyms-by-language-or-synonym-group /openapi/search-tools.json get /api/synonymsgroup/{identifier} Path segment is overloaded: use a language code (for example `en`) to list all synonym groups for that language (`getSynonymsByLanguage`). Use a numeric synonym group ID to fetch a single group (`getSynonymGroup`). # List Banners by Engine Source: https://docs.cludo.com/api-reference/list-banners-by-engine /openapi/search-tools.json get /api/banners/site/{engineId} Returns all banners configured for the given search engine. # List Quicklinks Source: https://docs.cludo.com/api-reference/list-quicklinks /openapi/search-tools.json get /api/engine/{engineId}/quicklinks Returns all quicklinks for the given search engine. # List Rankings by Engine Source: https://docs.cludo.com/api-reference/list-rankings-by-engine /openapi/search-tools.json get /api/rankings/site/{engineId} Returns all rankings configured for the given search engine. # API Reference Overview Source: https://docs.cludo.com/api-reference/overview Reference for Cludo API endpoints covering search, autocomplete, AI answers, indexing, and analytics, organized by capability with v3 and v4 badges. ## Which version should I use? | Scenario | Recommendation | | --------------------------- | ----------------------------------------------------------------------------------------- | | **New integration** | Use **v4** paths for search, autocomplete, AI Chat, AI Summary, and index management. | | **Existing v3 integration** | Your code continues to work. See [API Versions](/guides/migration-v3-to-v4) for guidance. | | **Search Tools** | Banners, rankings, quicklinks, and synonyms use **unversioned**`/api/` paths. | ## Base URLs | Region | Base URL | Customer IDs | | ------ | --------------------------- | -------------------- | | EU | `https://api.cludo.com` | Below 10,000,000 | | US | `https://api-us1.cludo.com` | 10,000,000 and above | [Full region details](/regions) ## Authentication | Scheme | When to use | | ------------------- | -------------------------------------------------------------------------- | | **SiteKey** | Search, Autocomplete, AI Chat, AI Summary, Tracking | | **Basic (API Key)** | Index management (PUT/PATCH/DELETE), queue URLs, search tools, bulk-delete | | **Anonymous** | Tracking, AI feedback and click tracking | [Full authentication guide](/authentication) *** ## Endpoint index ### Search | Endpoint | Path | Auth | Description | | ----------------------------------------------------- | -------------------------------------------------- | -------------- | -------------------------------------------------- | | [Search](/api-reference/v4/search/search) | `POST /api/v4/{customerId}/{engineId}/search` | SiteKey, Basic | Full-text search with filters, facets, and sorting | | [Autocomplete](/api-reference/v4/search/autocomplete) | `GET /api/v4/{customerId}/{engineId}/autocomplete` | SiteKey, Basic | Typeahead suggestions for search inputs | ### AI | Endpoint | Path | Auth | Description | | ------------------------------------------ | ---------------------------------- | -------------- | ---------------------------------------------------------- | | [AI Chat](/api-reference/v4/ai/chat) | `POST .../search/answer` | SiteKey, Basic | AI-powered conversational answers (standard and streaming) | | [AI Summary](/api-reference/v4/ai/summary) | `POST .../search/summarize` | SiteKey, Basic | Summarize search results with AI | | [AI Summary](/api-reference/v4/ai/summary) | `POST .../search/summarize/stream` | SiteKey, Basic | Streaming variant of AI Summary | ### Content & Indexing | Endpoint | Path | Auth | Description | | ------------------------------------------------------------------------------- | -------------------------------------------------- | ----- | ---------------------------------- | | [Index Management](/api-reference/v4/content/index-management) | `PUT/PATCH/DELETE .../index/{crawlerId}/documents` | Basic | Push, update, and delete documents | | [Queue URLs](/api-reference/queue-urls) | `POST .../crawler/{crawlerId}/paths` | Basic | Queue URLs for crawling | | [Bulk Delete](/api-reference/v4/content/index-management#bulk-delete-documents) | `POST .../documents/bulk-delete` | Basic | Delete documents matching a filter | | | | | | ### Tracking | Endpoint | Path | Auth | Description | | ------------------------------------------------------- | ------------------------------------ | --------------------- | ----------------------------------- | | [Track Search Query](/api-reference/track-search-query) | `POST /api/v3/.../pushstat/querylog` | Any (incl. Anonymous) | Record search queries for analytics | | [Track Result Click](/api-reference/track-result-click) | `POST /api/v3/.../pushstat/clicklog` | Any (incl. Anonymous) | Record result clicks for analytics | ### Search Tools | Endpoint | Path | Auth | Description | | -------------------------------------------------------------------- | -------------------- | ----- | ---------------------------------- | | [Banners](/api-reference/list-banners-by-engine) | `/api/banners` | Basic | Promote content in search results | | [Rankings](/api-reference/list-rankings-by-engine) | `/api/rankings` | Basic | Pin pages to top of search results | | [Quicklinks](/api-reference/list-quicklinks) | `/api/quicklinks` | Basic | Redirect on specific search terms | | [Synonyms](/api-reference/get-synonyms-by-language-or-synonym-group) | `/api/synonymsgroup` | Basic | Define term equivalence groups | *** ## v4-only Features These capabilities have no v3 equivalent: * **AI Chat and AI Summary**: conversational answers and document summarization powered by LLMs * **Index Management**: replace, patch, and bulk-delete documents with advanced filtering (replaces v3 Content Management) # Partial Update Source: https://docs.cludo.com/api-reference/partial-update /openapi/index-management.json patch /api/v4/{customerId}/index/{crawlerId}/documents Updates only the fields you send for each document. Request body is a JSON array of document objects in the same shape as replace; omit fields you do not want to change. # Queue URLs Source: https://docs.cludo.com/api-reference/queue-urls /openapi/index-management.json post /api/v4/{customerId}/crawler/{crawlerId}/paths Queues a list of URLs for the specified crawler. Request body must be a JSON array of URL strings. **Prerequisite:** the crawler must be manually activated in MyCludo before queued URLs will be indexed. URLs queued against an inactive crawler are accepted by this endpoint (you will get `200 OK` with `Status: Ok` per URL) but they will sit in the queue and never be crawled. # Single Delete Source: https://docs.cludo.com/api-reference/single-delete /openapi/index-management.json delete /api/v4/{customerId}/index/{crawlerId}/documents Deletes one document from the index by its document ID, supplied as the required `documentId` query parameter. The document ID is the same value you used as `id` when indexing the document. For most integrations this is the document's **canonical URL** (e.g. `https://example.com/products/widget-pro`), not an internal numeric key. When the document ID contains reserved characters — which a full URL typically does (`?`, `&`, `=`, `#`, spaces) — URL-encode it before adding it to the query string so it is parsed correctly (e.g. `documentId=https%3A%2F%2Fexample.com%2Fproducts%2Fwidget-pro`). # Submit Feedback Source: https://docs.cludo.com/api-reference/submit-feedback /openapi/feedback.json post /api/v4/{customerId}/{engineId}/feedback Submit user feedback for search results including ratings and comments. # Track Result Click Source: https://docs.cludo.com/api-reference/track-result-click /openapi/tracking.json post /api/v3/{customerId}/{engineId}/search/pushstat/clicklog Record when a user clicks a search result. # Track Search Query Source: https://docs.cludo.com/api-reference/track-search-query /openapi/tracking.json post /api/v3/{customerId}/{engineId}/search/pushstat/querylog Record a search query event for analytics. # Update Banner Source: https://docs.cludo.com/api-reference/update-banner /openapi/search-tools.json put /api/banners/{bannerId} Replaces a banner. The banner `id` is taken from the URL path. # Update Quicklink Source: https://docs.cludo.com/api-reference/update-quicklink /openapi/search-tools.json put /api/quicklinks/{quicklinkId} Replaces a quicklink. The quicklink `id` is taken from the URL path. # Update Ranking Source: https://docs.cludo.com/api-reference/update-ranking /openapi/search-tools.json put /api/rankings/{rankingId} Replaces a ranking. The ranking `id` is taken from the URL path. # Update Synonym Group Source: https://docs.cludo.com/api-reference/update-synonym-group /openapi/search-tools.json put /api/synonymsgroup Updates a synonym group. # AI Chat Source: https://docs.cludo.com/api-reference/v4/ai/chat POST /api/v4/{customerId}/{engineId}/search/answer Returns a generative answer for the given question, with optional citations and multi-turn conversation support. For streaming AI Chat, citations are included inline in the streamed text by default, so `includeCitations` does not change the streamed output. You are viewing the **standard** endpoint which returns a complete JSON response. The streaming endpoint is the same path as standard with `/stream` appended: `POST /api/v4/{customerId}/{engineId}/search/answer/stream`. It accepts the same request body as the standard endpoint, but streams the response as plain text chunks. Citations are included inline in the streamed text by default, so `includeCitations` does not change the streaming response. Response headers include `Cludo-Conversation-Id` and `Cludo-Exchange-Id` for conversation tracking. *** ## Multi-turn conversations Pass the `conversationId` from a previous response to continue the conversation. For independent questions, omit `conversationId` to start fresh. *** # AI Search Overview Source: https://docs.cludo.com/api-reference/v4/ai/overview Learn how Cludo AI Chat and AI Summary endpoints deliver generative answers and summaries grounded in your search index, and how to enable them. ## Why AI-powered search? AI Search combines keyword matching with semantic search to understand query intent, not just exact words. This improves relevance when users phrase things differently than your indexed content. ### Key benefits * **Semantic understanding**: matches intent, not just keywords * **AI Chat**: conversational answers with citations * **AI Summary**: synthesizes search results into a concise summary ## Setting up an AI engine To enable AI Search on your engine: Log in to [MyCludo](https://my.cludo.com) and go to **Engines**. Create a new engine or edit an existing one. Expand the **Advanced options** section and enable **AI Search**. This activates semantic search and enables access to AI Chat and AI Summary features. Set up crawlers or push content. AI Search uses the same indexed content as standard search. All AI features require an AI-enabled engine. ## AI capabilities at a glance | Feature | Endpoint | What it does | | -------------------------- | ------------------------------------------ | -------------------------------------------------------------- | | **AI Search** | [Search](/api-reference/v4/search/search) | Automatic keyword + semantic ranking on AI-enabled engines | | **AI Chat** | [AI Chat](/api-reference/v4/ai/chat) | Conversational answers with citations (standard and streaming) | | **AI Summary** | [AI Summary](/api-reference/v4/ai/summary) | Synthesize search results into a summary | | **AI Summary (streaming)** | [AI Summary](/api-reference/v4/ai/summary) | Real-time streamed summaries | ## Authentication AI endpoints support the same authentication schemes as search: | Scheme | Use case | | ------------------- | --------------------------------------------------- | | **SiteKey** | Client-side integration (safe to expose in browser) | | **Basic (API Key)** | Server-side integration | See the [Authentication guide](/authentication) for token format details. # AI Summary Source: https://docs.cludo.com/api-reference/v4/ai/summary POST /api/v4/{customerId}/{engineId}/search/summarize Generates a summary across selected search results for a given query. You are viewing the **standard** endpoint which returns a complete JSON response. Generate AI-powered summaries from search result documents. The AI Summary endpoint works in tandem with the Search endpoint: first execute a search, then pass the search results as sources to generate a concise summary with citations. The streaming endpoint is the same path as standard with `/stream` appended: `POST /api/v4/{customerId}/{engineId}/search/summarize/stream`. It accepts the same request body as the standard endpoint, but streams the response as chunked plain text. Streaming responses set `Cludo-Summary-Id` and `Cludo-Summary-Request-Id` headers for tracking. *** ## Workflow **Step 1: Execute a search** Call the [Search](/api-reference/v4/search/search) endpoint and extract from the response: * `QueryId` → use as the `queryId` parameter * `TypedDocuments[].Fields.Id.Value` → use as the `id` for each source * Source `fields` → prefer `Title` and `Content` when those fields are available **Step 2: Generate the summary** Pass the extracted values to this endpoint along with your query and source configuration. Send no more than 5 sources. *** ## Feature availability **`answerLength` and `customPrompt` are in limited availability.** These options are currently in an early test phase and are only enabled for select customers running on specific servers. They are not active by default, so supplying these values will not change the generated output unless the features have been enabled for your account. To discuss enabling them for your setup, contact your account manager and share your customer ID and engine ID. **`includeCitations` applies to the streaming endpoint only.** This parameter has no effect on the standard summary response. Use the streaming endpoint (`/search/summarize/stream`) if you need source URLs included in the output. # Pre-search Suggestions Source: https://docs.cludo.com/api-reference/v4/search-tools/pre-search-suggestions Fetch and render curated Pre-search Suggestions before a visitor starts typing in a custom search UI. Pre-search Suggestions are curated search terms configured in MyCludo. Use them to show helpful suggestions in an empty search input, before the visitor starts typing. This guide shows API-only customers how to read the configured terms from the same public settings endpoint used by CludoJS. ## Prerequisites From MyCludo, collect the values for the engine where Pre-search Suggestions are configured: | Value | Description | | --------------- | -------------------------------------------------------------------------------------- | | **Customer ID** | The customer ID for your Cludo account | | **Engine ID** | The engine where suggestions were configured | | **Search key** | The public search or site key for the engine | | **Region** | EU customers use `https://api.cludo.com`; US customers use `https://api-us1.cludo.com` | The feature must also be enabled on your subscription. If **Tools > Pre-search Suggestions** in MyCludo lets you save terms, the feature is enabled. ## Step 1: Build the SiteKey authorization header The request uses SiteKey authentication. Build the token by Base64-encoding `{customerId}:{engineId}:{searchKey}`: ```text theme={null} Authorization: SiteKey ``` ## Step 2: Call the public settings endpoint Fetch the website public settings for the engine: ```bash theme={null} curl https://api.cludo.com/api/v3/{customerId}/{engineId}/websites/publicsettings ``` Use the regional base URL that matches your customer ID: | Customer ID | Region | Base URL | | -------------------- | ------ | --------------------------- | | Below 10,000,000 | EU | `https://api.cludo.com` | | 10,000,000 and above | US | `https://api-us1.cludo.com` | ## Step 3: Parse `instantSuggestionsConfiguration` The response contains many website settings. The Pre-search Suggestions field is `instantSuggestionsConfiguration`. This field is returned as a JSON-encoded string, so parse the response JSON first, then parse `instantSuggestionsConfiguration` a second time: ```json theme={null} { "suggestions": ["popular term 1", "popular term 2", "popular term 3"], "showRecentSearches": true, "limit": 5 } ``` | Field | Description | | -------------------- | -------------------------------------------------------------- | | `suggestions` | Curated terms entered in MyCludo, returned in display order | | `limit` | Maximum number of items to show | | `showRecentSearches` | Whether your UI should also show the visitor's recent searches | Cludo does not store recent searches for the visitor. If `showRecentSearches` is `true`, store and merge recent searches client-side, for example in `localStorage`. # Autocomplete Source: https://docs.cludo.com/api-reference/v4/search/autocomplete GET /api/v4/{customerId}/{engineId}/autocomplete Returns typeahead suggestions as the user types. Autocomplete can be configured to display document titles, but this is an account-wide setting — contact Cludo support to enable it. ## Autocomplete strategies Autocomplete can be configured to display document titles instead of plain suggestions. This is an account-wide setting — contact Cludo support to enable it. When title-based autocomplete is enabled, suggestions are backed by real indexed documents. You can narrow results using the `filters` query parameter with any indexed field: # Search Source: https://docs.cludo.com/api-reference/v4/search/search POST /api/v4/{customerId}/{engineId}/search Execute a full-text search query with filters, facets, and sorting. The Search endpoint accepts an optional `responseType` body field that controls the response format. See [Autocomplete → responseType](/api-reference/v4/search/autocomplete#responsetype-jsonobject-vs-jsonhtml) for the comparison; for Search, set it as a JSON body field rather than a query parameter. *** ## Full search request example A real-world search rarely sends just a `query`. The example below exercises most body parameters at once — pagination, field selection, highlighting, facets, range facets, include/exclude filters, value boosting, sorting, and related searches — with representative values you can adapt. ```bash cURL theme={null} # Use https://api-us1.cludo.com for the US region curl -X POST "https://api.cludo.com/api/v4/{customerId}/{engineId}/search" \ -H "Authorization: SiteKey {token}" \ -H "Content-Type: application/json" \ -d '{ "query": "search api", "operator": "AND", "page": 1, "perPage": 20, "responseType": "JsonObject", "fields": ["Title", "Url", "Description", "Category", "Language", "Date"], "highlight": true, "enableFacetFiltering": true, "enableRelatedSearches": true, "filters": { "Category": ["Documentation", "Guides"], "Language": ["en"] }, "notFilters": { "Status": ["Archived"] }, "rangeFacets": { "Published this year": { "fieldName": "Date_date", "ranges": [{ "from": "2026-01-01", "to": "2026-12-31" }] }, "Published last year": { "fieldName": "Date_date", "ranges": [{ "from": "2025-01-01", "to": "2025-12-31" }] } }, "valueBoost": { "Category": ["Featured"] }, "sort": { "Date_date": "Descending" } }' ``` ```python Python theme={null} import requests # Use https://api-us1.cludo.com for the US region url = "https://api.cludo.com/api/v4/{customerId}/{engineId}/search" headers = { "Authorization": "SiteKey {token}", "Content-Type": "application/json", } payload = { "query": "search api", "operator": "AND", "page": 1, "perPage": 20, "responseType": "JsonObject", "fields": ["Title", "Url", "Description", "Category", "Language", "Date"], "highlight": True, "enableFacetFiltering": True, "enableRelatedSearches": True, "filters": { "Category": ["Documentation", "Guides"], "Language": ["en"], }, "notFilters": { "Status": ["Archived"], }, "rangeFacets": { "Published this year": { "fieldName": "Date_date", "ranges": [{"from": "2026-01-01", "to": "2026-12-31"}], }, "Published last year": { "fieldName": "Date_date", "ranges": [{"from": "2025-01-01", "to": "2025-12-31"}], }, }, "valueBoost": { "Category": ["Featured"], }, "sort": { "Date_date": "Descending", }, } response = requests.post(url, json=payload, headers=headers) print(response.json()) ``` ```javascript JavaScript theme={null} // Use https://api-us1.cludo.com for the US region const payload = { query: "search api", operator: "AND", page: 1, perPage: 20, responseType: "JsonObject", fields: ["Title", "Url", "Description", "Category", "Language", "Date"], highlight: true, enableFacetFiltering: true, enableRelatedSearches: true, filters: { Category: ["Documentation", "Guides"], Language: ["en"], }, notFilters: { Status: ["Archived"], }, rangeFacets: { "Published this year": { fieldName: "Date_date", ranges: [{ from: "2026-01-01", to: "2026-12-31" }], }, "Published last year": { fieldName: "Date_date", ranges: [{ from: "2025-01-01", to: "2025-12-31" }], }, }, valueBoost: { Category: ["Featured"], }, sort: { Date_date: "Descending", }, }; const response = await fetch( "https://api.cludo.com/api/v4/{customerId}/{engineId}/search", { method: "POST", headers: { "Authorization": "SiteKey {token}", "Content-Type": "application/json", }, body: JSON.stringify(payload), }, ); const data = await response.json(); console.log(data); ``` ```typescript TypeScript theme={null} // Use https://api-us1.cludo.com for the US region const payload = { query: "search api", operator: "AND", page: 1, perPage: 20, responseType: "JsonObject", fields: ["Title", "Url", "Description", "Category", "Language", "Date"], highlight: true, enableFacetFiltering: true, enableRelatedSearches: true, filters: { Category: ["Documentation", "Guides"], Language: ["en"], }, notFilters: { Status: ["Archived"], }, rangeFacets: { "Published this year": { fieldName: "Date_date", ranges: [{ from: "2026-01-01", to: "2026-12-31" }], }, "Published last year": { fieldName: "Date_date", ranges: [{ from: "2025-01-01", to: "2025-12-31" }], }, }, valueBoost: { Category: ["Featured"], }, sort: { Date_date: "Descending", }, }; const response = await fetch( "https://api.cludo.com/api/v4/{customerId}/{engineId}/search", { method: "POST", headers: { "Authorization": "SiteKey {token}", "Content-Type": "application/json", }, body: JSON.stringify(payload), }, ); const data: unknown = await response.json(); console.log(data); ``` *** ## Combining filters and facets (AND / OR) Faceted search is driven by the `filters` and `notFilters` objects. Each key is an indexed field name and each value is an array of values. The way they combine is fixed and predictable: | Combination | Behaviour | | ------------------------------------- | ------------------------------------------------------------------------------ | | Multiple values **in the same field** | Combined with **OR** — a document matches if it has *any* of the listed values | | Multiple **different fields** | Combined with **AND** — a document must match *every* field's condition | | `notFilters` | Combined with **AND NOT** — matching documents are excluded | The top-level `operator` (`AND` / `OR`) is separate from facet filtering. It controls how the **words in `query`** are matched against the index — it does **not** change how `filters` are combined. Filters always follow the OR-within-field, AND-across-fields rules above. ### OR within a single field Return documents in **either** `Documentation` **or** `Guides`: ```json theme={null} { "query": "search api", "filters": { "Category": ["Documentation", "Guides"] } } ``` ### AND across multiple fields Return documents that are in `Documentation` **and** written in English **and** published — every field condition must hold: ```json theme={null} { "query": "search api", "filters": { "Category": ["Documentation"], "Language": ["en"], "Status": ["Published"] } } ``` ### Combining OR within fields and AND across fields The two rules stack. The request below means: (`Documentation` **OR** `Guides`) **AND** (`en` **OR** `da`): ```json theme={null} { "query": "search api", "filters": { "Category": ["Documentation", "Guides"], "Language": ["en", "da"] } } ``` ### Excluding values with notFilters Keep the include filters above but **exclude** anything that is `Archived` or `Draft` (the exclusions are AND-NOT'd onto the result): ```json theme={null} { "query": "search api", "filters": { "Category": ["Documentation", "Guides"] }, "notFilters": { "Status": ["Archived", "Draft"] } } ``` Need all words in the query to match *and* narrow results by facets? Set `"operator": "AND"` for the text query and add your `filters` — they work together: the `operator` tightens the keyword match while `filters` apply the facet AND/OR logic. ## Filter value formats `filters`, `notFilters`, and `postFilters` share the same value grammar. Each key is normally an **indexed field name** mapped to an array of allowed values. In addition, three **reserved keys** — `range`, `date`, and `geo_distance` — express numeric ranges, date ranges, and geo-distance filters. Each reserved key takes a flat array of positional arguments, and you can repeat the argument group to add several filters of that type at once. ### Value Match a field against one or more exact values (the common facet case): ```json theme={null} { "filters": { "Category": ["Publications", "Events"], "DocumentType": ["PDF"] } } ``` ### Range (numeric) Reserved key `range`, in groups of three: `[field, min, max]`. Bounds are inclusive (`>=` / `<=`); pass an empty string to leave a bound open. Use `.` as the decimal separator. ```json theme={null} { "filters": { "range": ["Price", "20", "100", "WheelRimSize", "25.5", ""] } } ``` ### Date range Reserved key `date`, in groups of three: `[field, from, to]`. Values are ISO 8601 strings; an empty string leaves that side open. Date fields are the indexed date fields (typically `_date`-suffixed). ```json theme={null} { "filters": { "date": ["PublishDate_date", "2025-01-01", "2025-12-31"] } } ``` Accepted formats include `2017-06-13`, `2017-06-13T02:50:25Z`, and `2017-06-13T02:50:25+00:00`. When no time is given, the whole day is included. ### Geo distance Reserved key `geo_distance`, exactly five items: `[field, latitude, longitude, distance, unit]`. The field is the `_geo_point`-suffixed geo field. ```json theme={null} { "filters": { "geo_distance": ["Location_geo_point", "50.3453456", "-9.546456", "100", "Kilometers"] } } ``` `unit` is one of `Inch`, `Feet`, `Yards`, `Miles`, `NauticalMiles`, `Kilometers`, `Meters`, `Centimeters`, `Millimeters`. `range`, `date`, and `geo_distance` are reserved keys inside the filter object — you cannot use them as literal field names. All four formats work identically in `filters`, `notFilters`, and `postFilters`. *** ## Post-filtering (narrow results without changing facet counts) `filters` and `notFilters` run **with** the query, so they shape both the ranked results **and** the `Facets` counts. `postFilters` runs **after** the query as a post-filter: it narrows the documents returned **without** recomputing the facet counts. This is what powers classic faceted navigation — when a user ticks one value in a facet you want the results to narrow, but the *other* counts in that facet should stay visible so they can broaden their selection again. | Field | Type | Notes | | --------------------- | ------ | --------------------------------------------------------------------------------- | | `postFilters` | object | Same `{ "Field": ["value", …] }` shape as `filters`. Filters results, not facets. | | `postFiltersOperator` | string | `AND` (default) — every field must match. `OR` — any field may match. | To make post-filters *also* apply to the returned facet counts, set `"enableFacetFiltering": true`. `postFilters` cannot be combined with `advancedPostFilter` in the same request. ```json theme={null} { "query": "search api", "filters": { "Category": ["Documentation", "Guides"] }, "postFilters": { "Language": ["en"] }, "postFiltersOperator": "AND" } ``` *** ## Pagination | Field | Type | Notes | | ------ | --------- | ------- | | `page` | integer | | | | `perPage` | integer | `TotalDocument` in the response gives the total number of matching documents — use it together with `perPage` to compute how many pages exist. If you need result counts higher than the deep-pagination cap, narrow the query with filters instead of paginating further. # Authentication Source: https://docs.cludo.com/authentication Authenticate Cludo API requests using HTTP Basic credentials or a SiteKey, including when to use each method and how to send the Authorization header. The Cludo API supports two authentication schemes. Which one to use depends on where the request is made and which endpoint you call. | Scheme | Use case | | ------------------- | ---------------------------------------------------------------------------------------------------------- | | **Basic (API Key)** | Default for API requests, server-side integrations, index management, crawler URL queues, and search tools | | **SiteKey** | Public client-side search where an API key must not be exposed | Unless an endpoint says otherwise, use Basic authentication. SiteKey is only intended for browser-facing search integrations. *** ## Basic (API Key) aauthentication Used for API requests from a trusted backend, scripts, and integrations. Use Basic authentication for index management, crawler URL queues, search tools, and any endpoint where you can keep the API key private. ### Building the token ```bash theme={null} # Format: base64(customerId:apiKey) echo -n "3:c8fk2L9mK4pQ" | base64 # MzpjOGZrMkw5bUs0cFE= ``` ```bash cURL theme={null} # Use https://api-us1.cludo.com for the US region curl -X POST "https://api.cludo.com/api/v4/3/6/search" \ -H "Authorization: Basic MzpjOGZrMkw5bUs0cFE=" \ -H "Content-Type: application/json" \ -d '{"query": "test"}' ``` ```python Python theme={null} import requests # Use https://api-us1.cludo.com for the US region url = "https://api.cludo.com/api/v4/3/6/search" headers = { "Authorization": "Basic MzpjOGZrMkw5bUs0cFE=", "Content-Type": "application/json", } response = requests.post(url, json={"query": "test"}, headers=headers) print(response.json()) ``` ```javascript JavaScript theme={null} // Use https://api-us1.cludo.com for the US region const response = await fetch("https://api.cludo.com/api/v4/3/6/search", { method: "POST", headers: { "Authorization": "Basic MzpjOGZrMkw5bUs0cFE=", "Content-Type": "application/json", }, body: JSON.stringify({ query: "test" }), }); const data = await response.json(); console.log(data); ``` ```typescript TypeScript theme={null} // Use https://api-us1.cludo.com for the US region const response = await fetch("https://api.cludo.com/api/v4/3/6/search", { method: "POST", headers: { "Authorization": "Basic MzpjOGZrMkw5bUs0cFE=", "Content-Type": "application/json", }, body: JSON.stringify({ query: "test" }), }); const data: unknown = await response.json(); console.log(data); ``` ### Where to find your credentials Log in to [MyCludo](https://my.cludo.com) and navigate to **Account Settings** to find your Customer ID and API key. *** ## SiteKey aauthentication Used for public website search widgets and other client-side search integrations. SiteKey authentication exists so browser code can call search-related endpoints without exposing your API key. ### Building the token ```bash theme={null} # Format: base64(customerId:engineId:SearchKey) # "SearchKey" is a fixed, literal string. Do not replace it with a value. echo -n "3:6:SearchKey" | base64 # Mzo2OlNlYXJjaEtleQ== ``` A SiteKey is tied to one specific engine. You cannot use a SiteKey from one engine to authenticate requests to another engine. ```bash cURL theme={null} # Use https://api-us1.cludo.com for the US region curl -X POST "https://api.cludo.com/api/v4/3/6/search" \ -H "Authorization: SiteKey Mzo2OlNlYXJjaEtleQ==" \ -H "Content-Type: application/json" \ -d '{"query": "test"}' ``` ```python Python theme={null} import requests # Use https://api-us1.cludo.com for the US region url = "https://api.cludo.com/api/v4/3/6/search" headers = { "Authorization": "SiteKey Mzo2OlNlYXJjaEtleQ==", "Content-Type": "application/json", } response = requests.post(url, json={"query": "test"}, headers=headers) print(response.json()) ``` ```javascript JavaScript theme={null} // Use https://api-us1.cludo.com for the US region const response = await fetch("https://api.cludo.com/api/v4/3/6/search", { method: "POST", headers: { "Authorization": "SiteKey Mzo2OlNlYXJjaEtleQ==", "Content-Type": "application/json", }, body: JSON.stringify({ query: "test" }), }); const data = await response.json(); console.log(data); ``` ```typescript TypeScript theme={null} // Use https://api-us1.cludo.com for the US region const response = await fetch("https://api.cludo.com/api/v4/3/6/search", { method: "POST", headers: { "Authorization": "SiteKey Mzo2OlNlYXJjaEtleQ==", "Content-Type": "application/json", }, body: JSON.stringify({ query: "test" }), }); const data: unknown = await response.json(); console.log(data); ``` *** ## Try it: build your token Use the tool below to generate your SiteKey or Basic authorization header and a ready-to-run cURL command. Switch between **SiteKey** and **Basic** to see the correct prefix for each scheme. # Crawler Source: https://docs.cludo.com/concepts/crawler Understand how Cludo crawlers discover, fetch, and feed website or feed content into an engine's index, and how crawl schedules and sources are configured. A **crawler** is a content source attached to an engine. It produces the documents that end up in the search index — either by fetching pages on a schedule, or by accepting documents you push through the API. An engine can have one or more crawlers (for example, a website crawler plus a feed for product data). Every API path that writes to the index takes a `crawlerId`: [Index Management](/api-reference/v4/content/index-management) uses `/index/{crawlerId}/documents` to push, patch, or delete documents, and the queue endpoint at `/crawler/{crawlerId}/paths` adds URLs to a fetch queue. Crawlers themselves are created and configured in [MyCludo](https://my.cludo.com) under **Crawlers**. See [Pushing Content](/guides/pushing-content) for the end-to-end workflow. # Document and Fields Source: https://docs.cludo.com/concepts/document-and-fields How Cludo structures indexed content as documents and fields, including standard fields, custom fields, and how field types affect search and filtering. A **document** is a single indexed item — typically a page, article, or product. Each document has a stable `id` (often the canonical URL) and a `fields` object containing the searchable and displayable values. Create or update documents through [Index Management](/api-reference/v4/content/index-management); the request body is a plain JSON array of `{ id, fields }` objects. The same field names appear back on the [Search](/api-reference/v4/search/search) response under `TypedDocuments[].Fields`. **Fields** are keyed by name and are case-sensitive. Common fields include `Title`, `Url`, `Description`, `Date`, `Category`, `Language`, and `Content`. When you push content through [Index Management](/api-reference/v4/content/index-management), the field shape is defined by the payload itself — you can include any custom fields directly in the `fields` object and they will be searchable and displayable in the [Search](/api-reference/v4/search/search) response. Using a field as a **facet or filter** requires a one-time backend setup on Cludo's side. Email [Cludo support](mailto:support@cludo.com) with the engine ID and the field names you want enabled for faceting or filtering. If you are pushing content through the API, we recommend disabling scheduled crawling on the crawler in [MyCludo](https://my.cludo.com) so the index only contains your pushed content. For crawler-fetched content, custom fields are configured per-crawler in MyCludo instead. # Engine Source: https://docs.cludo.com/concepts/engine A Cludo engine groups the index, crawler, ranking, and configuration that powers one search experience. Learn how engines map to your sites and APIs. An **engine** is the unit of configuration that powers one search experience. It owns the indexed content, the search behavior (page rankings, synonyms, banners, AI features), and the credentials clients use to query it. Most accounts have one engine per site or property; you can have several when different audiences need different content or relevance tuning. Every API call that returns or scores documents takes an `engineId` in the path — see the [Search](/api-reference/v4/search/search) reference for the standard request shape. The engine ID is also embedded in [SiteKey](/authentication) tokens, so a SiteKey is always tied to one specific engine. Engines are created and configured in [MyCludo](https://my.cludo.com) under **Engines**. # Search Template Source: https://docs.cludo.com/concepts/search-template Cludo search templates pair a search input with a results display, providing prebuilt layouts you can customize instead of building a UI from scratch. A **Search Template** is a pre-built Cludo solution that bundles a search input with a results display, so you can drop search onto a site without building the UI yourself. Templates ship with default styling that you can customize. Search Templates are not exposed through the public API. If you are integrating against the API directly, you are not using a Search Template — you are building your own front-end against the [Search](/api-reference/v4/search/search) endpoint (and optionally the [React components Storybook](https://react.cludo.com/)). Two global templates are supported today: * **Rich Inline Template** — results appear on a dedicated search results page. This replaced the deprecated **Legacy Inline Template**. See [How to implement the Rich Inline Template](https://help.cludo.com/implementation/rich-inline-template/). * **Overlay** — results appear in an overlay on top of any page once a search is performed. This is implemented through the **Implementation** tab in MyCludo. If the pre-built templates don't fit your needs, you have two alternatives: a custom template (talk to your CSM) or building your own front-end against the API. For the full walkthrough — when to pick which template, what each one looks like, and how to customize the styling — see the Help Center article [What are search templates?](https://help.cludo.com/configuration/what-are-search-templates/). # FAQ Source: https://docs.cludo.com/faq Answers to common questions about Cludo API authentication, rate limits, regions, v3 vs v4 endpoints, indexing, and AI search features. **v4 is the recommended API version for new search, AI, and index-management integrations.** | API Area | Version | | --------------------- | ------------------------ | | Search & Autocomplete | v3 or v4 (both work) | | AI Chat & AI Summary | v4 only | | Index Management | v4 only | | Tracking | v3 only | | Search Tools | Unversioned (`/api/...`) | The main migration work is Index Management: v3 Content Management uses `/content/{crawlerId}/...`, while v4 uses `/index/{crawlerId}/documents`. If you use PushURLs, the v4 equivalent is `POST /api/v4/{customerId}/crawler/{crawlerId}/paths`. See [API Versions: v3 vs v4](/guides/migration-v3-to-v4) for details. For the full v3 API reference, see the [legacy documentation](https://docs.cludo.com/). *** ## Architecture | Component | Role | | --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Engine** | Holds your search index. Every API call references a `customerId` and `engineId`. | | **Crawler** | Fetches and indexes your website on a schedule. Optional if you push all content via the Content API. | | **Content API** | Lets you push, update, or delete documents directly — no crawling needed. Requires a `crawlerId` as an index container even if the crawler never actively crawls. | | **Analytics** | Populated by tracking events sent from your frontend. Requires the analytics script or manual API calls — events are not sent automatically. | A Crawler and the Content API can coexist on the same engine. If you use both, be aware that a scheduled crawl can overwrite pushed content on the same URLs. If you push all content via API, disable scheduled crawling in MyCludo. *** ## Search Use the `filters` parameter to include only results with matching field values: ```json theme={null} { "query": "*", "filters": { "Category": ["Guides", "Tutorials"] } } ``` You can filter on standard fields and custom crawler fields, as long as the field is available in your index and configured for filtering where required. Field names are case-sensitive, so use the exact field name from your crawler or pushed document configuration. To exclude values, use `notFilters`. To build filter UI counts, enable facets on the relevant fields and send `enableFacetFiltering: true`. See the [Search API reference](/api-reference/v4/search/search) for request parameters. AI Search combines keyword matching with semantic matching to improve relevance for natural-language queries. It is available when AI Search is enabled for your engine. Your search request can stay the same; Cludo handles how keyword and semantic matches are combined. Use the [Cludo API analytics script](https://help.cludo.com/analytics/) or send tracking events through the API. Query tracking uses `POST /api/v3/{customerId}/{engineId}/search/pushstat/querylog`, and click tracking uses `POST /api/v3/{customerId}/{engineId}/search/pushstat/clicklog`. Send both query and click events so analytics can connect searches to clicked results. See the [legacy API documentation](https://docs.cludo.com/) for the full v3 tracking reference. Use the `sort` parameter to order results by a field, including custom crawler fields that are configured for sorting. Sorting is commonly used for dates, titles, numeric fields, and custom metadata such as product price or content type. Search only returns content that has been indexed. A page may be missing from the index for several reasons: * The crawler is blocked. * The page is excluded by crawler rules. * The content is rendered in a way the crawler cannot pick up. * The page has not been crawled since it changed. See [Troubleshooting → Content indexing issues](/troubleshooting#content-indexing-issues). Facet counts are calculated server-side across all matching documents, not just the current page. They reflect how many documents in the full result set match each facet value — independent of `page` and `perPage`. To use facets, the relevant fields must be enabled for faceting. Contact [support@cludo.com](mailto:support@cludo.com) with your engine ID and field names, then include `enableFacetFiltering: true` in your search request. Yes. The `query` parameter accepts up to 300 characters. Requests with a longer query are rejected with a 400 error. See the [Search API reference](/api-reference/v4/search/search) for request parameters. *** ## AI Chat & AI Summary * **AI Chat** generates a conversational answer to a question, grounded in your search index. Supports multi-turn conversations. * **AI Summary** summarizes a set of search result documents. You provide the search results, and it returns a synthesized summary. Both support streaming and non-streaming modes. AI Chat requires the `AiChat` feature flag to be enabled on your engine. Contact [support@cludo.com](mailto:support@cludo.com) or check your engine settings in [MyCludo](https://my.cludo.com). This boolean field in the search response indicates whether AI has enough signal to attempt an answer for the query. If `true`, you can call the [AI Chat](/api-reference/v4/ai/chat) endpoint for an answer grounded in your indexed content. Treat `true` as a hint, not a guarantee — the AI streaming endpoint may still return an error (such as a 502) if the model is temporarily unavailable. Always implement a fallback that hides the AI panel gracefully rather than surfacing a raw error to the user. If the value is `false`, the query may be too broad, the matching indexed content may not contain enough answerable text, or the relevant website content may not be indexed because of crawler configuration or crawlability issues. AI Summary is generated from the documents you provide in the request. To influence the result, choose the search results or documents you pass to the summary endpoint carefully and make sure each document includes useful title, URL, and text fields. See the [AI Summary API reference](/api-reference/v4/ai/summary). *** ## Content management Use **v4 Index Management** for document replacement, partial updates, and deletion. It supports partial updates (PATCH), advanced bulk-delete filters, and uses your **crawler id** in paths such as `/index/{crawlerId}/documents`. See [Index Management](/api-reference/v4/content/index-management). If your v3 integration uses PushURLs to queue pages for crawling, use `POST /api/v4/{customerId}/crawler/{crawlerId}/paths` in v4. See [API Versions: v3 vs v4](/guides/migration-v3-to-v4) for version guidance. For the full v3 API reference, see the [legacy documentation](https://docs.cludo.com/). Check these common issues: 1. **Wrong crawler id:** v4 document APIs use `/index/{crawlerId}/documents` — use the crawler id from MyCludo (same id as in v3 `/content/{crawlerId}` flows). 2. **Missing useful fields:** Ensure each document has an `id` and meaningful fields such as `Title`, `Url`, and `Description`. 3. **Give it time:** Documents may take a few seconds to become searchable. 4. **Check your region:** EU credentials don't work against the US endpoint. 5. **Validate crawled URLs:** For website content, use the crawler URL test in MyCludo to verify that the crawler can fetch and index the page. See [Troubleshooting → Content Indexing](/troubleshooting#content-indexing-issues). You still need a **crawler entity** in MyCludo, but it does not need to actively crawl anything. The `crawlerId` in Content API paths (`/index/{crawlerId}/documents`) is an index container identifier, not a requirement to run crawls. Create a crawler in MyCludo, then disable scheduled crawling so it never runs automatically. If you leave scheduled crawling on, the crawler may overwrite or remove documents you pushed via the API. *** ## Analytics * **Total searches** counts every search event received, including repeated searches from the same user in the same session. * **Unique searches** counts only the first search for a given query within a session. If your popular searches all show the same low count, it usually means each search is being tracked as a separate unique event — often caused by missing or inconsistent session identifiers in the tracking payload. 1. **Analytics events:** If you built a custom search UI, you must send tracking events manually or install the [Cludo analytics script](https://help.cludo.com/analytics/). Events are not sent automatically. 2. **Both event types:** Send both query events (`querylog`) and click events (`clicklog`). Missing one means analytics will be incomplete. *** ## Still have questions? Email [support@cludo.com](mailto:support@cludo.com) with your customer ID, engine ID, and a description of your issue. # AI Integration Guide Source: https://docs.cludo.com/guides/ai-chat-integration Step-by-step guide to integrating Cludo AI Chat and AI Summary endpoints, including streaming responses, citations, and multi-turn conversations. Cludo offers multiple AI features that enhance search results by generating answers: * **AI Chat**: Users ask natural language questions and receive conversational answers with citations * **AI Summary**: Summarize a set of search results into a concise overview * **AI Mode**: A conversational follow-up flow that starts from an AI Summary and continues with AI Chat on the same thread ## Prerequisites * AI Search enabled on your Cludo engine * SiteKey or API Key credentials *** ## AI Chat AI Chat generates conversational answers grounded in your indexed content. Users ask a question, and the AI returns an answer with citations to source pages. For streaming AI Chat, citations are included inline in the streamed text by default. Setting `includeCitations` does not change the streaming response. ### Basic request ```bash EU theme={null} curl -X POST "https://api.cludo.com/api/v4/{customerId}/{engineId}/search/answer" \ -H "Authorization: SiteKey {token}" \ -H "Content-Type: application/json" \ -d '{ "question": "How do I install the search widget?", "includeCitations": true }' ``` ```bash US theme={null} curl -X POST "https://api-us1.cludo.com/api/v4/{customerId}/{engineId}/search/answer" \ -H "Authorization: SiteKey {token}" \ -H "Content-Type: application/json" \ -d '{ "question": "How do I install the search widget?", "includeCitations": true }' ``` ### Multi-turn conversations Pass the `conversationId` from a previous response to continue the conversation: ```json theme={null} { "question": "Can you give me more details?", "conversationId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890" } ``` For independent questions, omit `conversationId` to start fresh. ### Answer length Control verbosity with the `answerLength` parameter: | Value | Description | | ----------------- | ------------------------------- | | `"comprehensive"` | Full, detailed answer (default) | | `"concise"` | Brief, to-the-point answer | See the [AI Chat API reference](/api-reference/v4/ai/chat) for all parameters. *** ## AI Summary AI Summary synthesizes multiple search results into a single overview. Unlike AI Chat, you first run a search, then pass selected results to the summary endpoint. ### Workflow **Step 1:** Run a search to get results and a `queryId`: ```bash theme={null} curl -X POST "https://api.cludo.com/api/v4/{customerId}/{engineId}/search" \ -H "Authorization: SiteKey {token}" \ -H "Content-Type: application/json" \ -d '{"query": "getting started", "perPage": 5}' ``` **Step 2:** Pass selected results to the summary endpoint: Send no more than 5 sources. For each source, prefer the `Title` and `Content` fields when they are available. ```bash EU theme={null} curl -X POST "https://api.cludo.com/api/v4/{customerId}/{engineId}/search/summarize" \ -H "Authorization: SiteKey {token}" \ -H "Content-Type: application/json" \ -d '{ "query": "getting started", "queryId": "abc123...", "sources": [ {"id": "https://example.com/page1", "fields": ["Title", "Content"]}, {"id": "https://example.com/page2", "fields": ["Title", "Content"]} ], "includeCitations": true }' ``` ```bash US theme={null} curl -X POST "https://api-us1.cludo.com/api/v4/{customerId}/{engineId}/search/summarize" \ -H "Authorization: SiteKey {token}" \ -H "Content-Type: application/json" \ -d '{ "query": "getting started", "queryId": "abc123...", "sources": [ {"id": "https://example.com/page1", "fields": ["Title", "Content"]}, {"id": "https://example.com/page2", "fields": ["Title", "Content"]} ], "includeCitations": true }' ``` `includeCitations` applies only to the streaming endpoint (`/search/summarize/stream`) and has no effect on this standard summary response. Likewise, `answerLength` and `customPrompt` are in limited availability and only change the output for accounts where those features have been enabled — contact your account manager (with your customer ID and engine ID) to discuss enabling them. See the [AI Summary API reference](/api-reference/v4/ai/summary) for all parameters. *** ## AI Mode AI Mode is a conversational follow-up pattern: the first answer is grounded in your search results, and every follow-up keeps the same thread. From the user's perspective it's typically an "Ask AI" button that opens a chat panel on the search page. It does not have its own endpoint. AI Mode uses AI Summary for the first turn and AI Chat for every follow-up, threaded together on a single conversation id. ### Workflow AI Mode uses the **streaming** variants of both endpoints so the answers render progressively in the chat UI. **Step 1:** Run a search to get a `QueryId` and the top results, exactly as in [AI Summary, Step 1](#ai-summary). **Step 2:** Send the user's first question to the streaming AI Summary endpoint `/search/summarize/stream` with up to 5 source documents from Step 1 — same request body as in [AI Summary, Step 2](#ai-summary). Read the `summaryRequestId` from the `Cludo-Summary-Request-Id` response header — you'll use it as the conversation id for every follow-up. **Step 3:** Send every follow-up to the streaming AI Chat endpoint `/search/answer/stream`, passing the `summaryRequestId` from Step 2 as `conversationId`. Reuse the same `conversationId` for every subsequent follow-up so the AI keeps context. ```bash EU theme={null} curl -X POST "https://api.cludo.com/api/v4/{customerId}/{engineId}/search/answer/stream" \ -H "Authorization: SiteKey {token}" \ -H "Content-Type: application/json" \ -d '{ "question": "Can you give me more details on the installation step?", "conversationId": "{summaryRequestId from Step 2}" }' ``` ```bash US theme={null} curl -X POST "https://api-us1.cludo.com/api/v4/{customerId}/{engineId}/search/answer/stream" \ -H "Authorization: SiteKey {token}" \ -H "Content-Type: application/json" \ -d '{ "question": "Can you give me more details on the installation step?", "conversationId": "{summaryRequestId from Step 2}" }' ``` ### Continuing from an AI Summary on the search page If you already render an AI Summary above your search results, you can let users click a button on that summary to keep asking questions — without running a second `summarize` call. The shortcut: reuse the `summaryRequestId` you already received from the SERP's AI Summary as the `conversationId` on the first `/search/answer/stream` request. Display the existing summary as the first turn of the conversation client-side, then continue with the streaming AI Chat endpoint for every follow-up. ```json theme={null} { "question": "What about for the US data center?", "conversationId": "{summaryRequestId already shown on the search page}" } ``` See the [AI Summary API reference](/api-reference/v4/ai/summary) and [AI Chat API reference](/api-reference/v4/ai/chat) for all parameters. *** ## Collecting ffeedback Track user feedback to improve AI quality. Both AI Chat and AI Summary have feedback endpoints: ```javascript theme={null} const BASE_URL = "https://api.cludo.com"; // Use https://api-us1.cludo.com for US // AI Chat feedback async function submitChatFeedback(conversationId, exchangeId, rating) { await fetch( `${BASE_URL}/api/v4/${customerId}/${engineId}/search/answer/feedback`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ conversationId, exchangeId, rating }) } ); } // AI Summary feedback async function submitSummaryFeedback(summaryId, rating) { await fetch( `${BASE_URL}/api/v4/${customerId}/${engineId}/search/summarize/feedback`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ summaryId, rating }) } ); } ``` *** ## When to use wuse which | Use Case | Feature | | ------------------------------------------ | ---------- | | User asks a direct question | AI Chat | | Show a summary above search results | AI Summary | | Conversational follow-up questions | AI Chat | | Synthesize specific documents | AI Summary | | Follow-up questions on a summarized search | AI Mode | # Analytics Guide Source: https://docs.cludo.com/guides/analytics Track Cludo search queries, clicks, and search-as-you-type events to measure search performance and improve relevance using the analytics endpoints. Cludo provides comprehensive analytics to help you understand how users search, what they find, and where to improve. ## Tracking events Analytics data is populated by tracking events. The recommended client-side setup is the [Cludo API analytics script](https://help.cludo.com/implementation/how-to-implement-cludos-api-analytics-script/). If you use the React hooks from `@cludosearch/cludo-search-components`, analytics events are handled automatically by the components package. If you implement search directly via the API, send tracking events yourself. ### Client-side event tracking Track search events from your frontend. These endpoints accept any auth method, including anonymous requests with no auth header. ```bash cURL theme={null} # Use https://api-us1.cludo.com for the US region # Track a search query curl -X POST "https://api.cludo.com/api/v3/{customerId}/{engineId}/search/pushstat/querylog" \ -H "Content-Type: application/json" \ -d '{ "sw": "wireless headphones", "qid": "a3f2c1b8-4e9d-4a1c-9b2e-7f4d6e8a1c3d", "rc": "42", "dt": "desktop" }' # Track a result click curl -X POST "https://api.cludo.com/api/v3/{customerId}/{engineId}/search/pushstat/clicklog" \ -H "Content-Type: application/json" \ -d '{ "ls": "searchresult", "sw": "wireless headphones", "qid": "a3f2c1b8-4e9d-4a1c-9b2e-7f4d6e8a1c3d", "clurl": "https://example.com/products/widget-pro", "cli": "1", "title": "Widget Pro" }' ``` ```python Python theme={null} import requests BASE_URL = "https://api.cludo.com" # Use https://api-us1.cludo.com for the US region def track_search(customer_id, engine_id, query_id, query, result_count): requests.post( f"{BASE_URL}/api/v3/{customer_id}/{engine_id}/search/pushstat/querylog", json={ "sw": query, "qid": query_id, "rc": str(result_count), "dt": "desktop", }, ) def track_click(customer_id, engine_id, query_id, click_url, click_index, title): requests.post( f"{BASE_URL}/api/v3/{customer_id}/{engine_id}/search/pushstat/clicklog", json={ "ls": "searchresult", "sw": "search query", "qid": query_id, "clurl": click_url, "cli": str(click_index), "title": title, }, ) ``` ```javascript JavaScript theme={null} const BASE_URL = "https://api.cludo.com"; // Use https://api-us1.cludo.com for the US region async function trackSearch(customerId, engineId, queryId, query, resultCount) { await fetch( `${BASE_URL}/api/v3/${customerId}/${engineId}/search/pushstat/querylog`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ sw: query, qid: queryId, rc: String(resultCount), dt: "desktop", }), }, ); } async function trackClick(customerId, engineId, queryId, clickUrl, clickIndex, title) { await fetch( `${BASE_URL}/api/v3/${customerId}/${engineId}/search/pushstat/clicklog`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ ls: "searchresult", sw: "search query", qid: queryId, clurl: clickUrl, cli: String(clickIndex), title: title, }), }, ); } ``` ```typescript TypeScript theme={null} const BASE_URL = "https://api.cludo.com"; // Use https://api-us1.cludo.com for the US region async function trackSearch( customerId: number, engineId: number, queryId: string, query: string, resultCount: number, ): Promise { await fetch( `${BASE_URL}/api/v3/${customerId}/${engineId}/search/pushstat/querylog`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ sw: query, qid: queryId, rc: String(resultCount), dt: "desktop", }), }, ); } async function trackClick( customerId: number, engineId: number, queryId: string, clickUrl: string, clickIndex: number, title: string, ): Promise { await fetch( `${BASE_URL}/api/v3/${customerId}/${engineId}/search/pushstat/clicklog`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ ls: "searchresult", sw: "search query", qid: queryId, clurl: clickUrl, cli: String(clickIndex), title: title, }), }, ); } ``` The tracking body uses flat key-value pairs (for example `{"sw": "query", "qid": "..."}`). Do **not** wrap them in a `values` object. See [API Reference → Tracking](/api-reference/overview#tracking) for the full list of parameters. ### Server-side tracking and IP forwarding If your integration sends tracking events from a backend rather than directly from the browser, the API receives your server's IP instead of the real user IP. This affects analytics deduplication and geographic data. To pass the real client IP, include it as an `ip` field in the request body: ```javascript theme={null} body: JSON.stringify({ sw: query, qid: queryId, rc: String(resultCount), dt: "desktop", ip: "203.0.113.42" // real client IP captured server-side }) ``` The tracking endpoints do not read the `X-Real-IP`, `X-Forwarded-For`, or `Forwarded` headers. To pass a client IP from a server-side integration, use the `ip` body field. ## Search-as-you-type implementations If your implementation fires search requests on every keystroke (search-as-you-type, or SAYT), follow the three steps below. Skipping them is the most common cause of noisy analytics. Symptoms include partial keystroke queries filling up Searches Without Results, a 0% click-through rate, and every search appearing as "ineffective" in the dashboard. Add `searchContext: "sayt"` to the body of [search requests](/api-reference/v4/search/search) fired on each keystroke. This tells the backend to classify them as SAYT and exclude them from Dashboard analytics (Popular Searches, Trending, etc.). ```javascript theme={null} body: JSON.stringify({ query: partialQuery, searchContext: "sayt" // keystroke search; omit for committed searches }) ``` Call [Track Search Query](/api-reference/track-search-query) (`querylog`) only when the user commits a final search, on Enter or explicit submission, not on every debounced keystroke. Logging every partial query produces rows like `r`, `ri`, `riv`, `rive`... in Searches Without Results. Call [Track Result Click](/api-reference/track-result-click) (`clicklog`) whenever a user clicks a result. Missing click events is the sole cause of a 0% click-through rate and all searches appearing as "ineffective" in the dashboard. ## Analytics setup checklist Use this checklist to confirm every analytics event is wired up correctly. Missing a required field is the most common cause of gaps in the [Dashboard](https://my.cludo.com). ### Every tracking call * Correct region base URL: `https://api.cludo.com` (EU, customer IDs below 10,000,000) or `https://api-us1.cludo.com` (US). * `{customerId}` and `{engineId}` in the path match the search that produced the `qid` (a mismatch returns `404`). ### Track Search Query (`querylog`) See [Track Search Query](/api-reference/track-search-query) for the full parameter reference. * `sw` — the search query the user submitted (**required**). * `qid` — the `QueryId` copied from the search response (**required**). * `rc` — number of results returned (needed for Searches Without Results). * `dt` — device type (`mobile`, `tablet`, or `desktop`). * `sid` / `qsid` — session and query-session IDs to stitch events per visit. * `fquery` — spell-corrected query, when the user saw the corrected version. * `refurl` — URL of the page where the search happened (the destination page). * `refpt` — title of the page where the search happened. ### Track Result Click (`clicklog`) See [Track Result Click](/api-reference/track-result-click) for the full parameter reference. * `qid` — links the click back to its originating search. * `clurl` — URL of the clicked result. * `cli` — rank of the clicked item in the result list. * `ls` — `searchresult` for organic clicks, `banner` for banner clicks. * `sw` and `title` — the query and the clicked result's title. * `cloi` — banner ID, required when `ls` is `banner`. * `refurl` — URL of the page where the click happened (the destination page). * `refpt` — title of the page where the click happened. ## Viewing analytics Analytics data is available in the [Cludo Dashboard](https://my.cludo.com). The dashboard provides: * **Search term performance**: top queries, zero-result queries, content gaps * **Search volume over time**: total and trending search volume * **Click-through rate**: are users finding what they need? * **AI analytics**: volume & feedback scores # API Versions: v3 vs v4 Source: https://docs.cludo.com/guides/migration-v3-to-v4 Compare Cludo API v3 and v4 endpoints, see which version supports each feature, and plan a migration from legacy v3 calls to the modern v4 API. Not all Cludo APIs use the same version. This guide explains exactly which version to use for each feature. *** ## The short version | Feature | Which Version? | | ---------------------------------------------------------- | ------------------------------------- | | **Search & Autocomplete** | Use **v4** (v3 also works) | | **AI Chat & AI Summary** | Use **v4** (only available in v4) | | **Push/manage documents** | Use **v4** Index Management | | **Queue URLs for crawling** | Use **v4** | | **Analytics tracking** | Use **v3** (querylog, clicklog) | | **Search tools** (banners, rankings, quicklinks, synonyms) | **No version** - use `/api/...` paths | *** ## Search & Autocomplete **Use v4 for new integrations.** Both v3 and v4 work and return compatible responses, but v4 is the current version. ```text theme={null} POST /api/v4/{customerId}/{engineId}/search GET /api/v4/{customerId}/{engineId}/autocomplete ``` *** ## AI Chat & AI Summary **v4 only.** These features do not exist in v3. ```text theme={null} POST /api/v4/{customerId}/{engineId}/search/answer (AI Chat) POST /api/v4/{customerId}/{engineId}/search/summarize (AI Summary) ``` *** ## Pushing documents (Index Management) **Use v4.** The v4 Index Management API replaced v3 Content Management. * Use `PUT` to replace/create documents * Use `PATCH` to update specific fields (new in v4) * Use `DELETE` to remove documents ```text theme={null} PUT /api/v4/{customerId}/index/{crawlerId}/documents PATCH /api/v4/{customerId}/index/{crawlerId}/documents DELETE /api/v4/{customerId}/index/{crawlerId}/documents ``` *** ## Queue URLs for crawling **Use v4.** If you previously used v3 PushURLs, the v4 equivalent is: ```text theme={null} POST /api/v4/{customerId}/crawler/{crawlerId}/paths ``` *** ## Analytics tracking **Use v3.** There is no v4 version of the tracking endpoints. Continue using the v3 paths: ```text theme={null} POST /api/v3/{customerId}/{engineId}/search/pushstat/querylog (track searches) POST /api/v3/{customerId}/{engineId}/search/pushstat/clicklog (track clicks) ``` *** ## Search Tools (Banners, Rankings, Quicklinks, Synonyms) **No version number.** These endpoints use unversioned `/api/...` paths. Do not add `/v3` or `/v4`: ```text theme={null} /api/banners/... /api/rankings/... /api/quicklinks/... /api/synonymsgroup/... ``` See [Search Tools](/api-reference/overview#search-tools) for the full API reference. *** ## Summary * **New integrations**: Use v4 for everything except tracking (v3) and search tools (unversioned) * **Existing v3 integrations**: Search and autocomplete continue to work on v3. Migrate content management to v4 Index Management when ready. * **Tracking**: Always v3 * **Search tools**: Never add a version number # Pushing Content Source: https://docs.cludo.com/guides/pushing-content Push custom documents into a Cludo search index using the Index Management API, including payload structure, batching, updates, and deletions. Push custom content to your search index when you need to index content that isn't available via web crawling, such as database records, CMS content, or internal documents. ## v4 Index Management (recommended) **Auth:** Basic (API Key) The request body for document operations is a **plain JSON array** of document objects. ### Create or replace documents Upsert documents. If a document with the same ID exists, it's replaced. Each document may optionally include a top-level `type` (`"PageContent"` or `"FileContent"`) as a sibling of `id` and `fields` — not inside `fields`. It defaults to `"PageContent"`; use `"FileContent"` for files such as PDFs or DOCX so they are treated as file results in the index. ```bash EU theme={null} curl -X PUT "https://api.cludo.com/api/v4/{customerId}/index/{crawlerId}/documents" \ -H "Authorization: Basic {base64(customerId:apiKey)}" \ -H "Content-Type: application/json" \ -d '[ { "id": "product-123", "type": "PageContent", "fields": { "Title": "Widget Pro", "Description": "Our most popular widget...", "Url": "https://example.com/products/widget-pro", "Category": "Products", "Price": "99.00" } }, { "id": "product-456", "type": "FileContent", "fields": { "Title": "Widget Basic", "Description": "Great for getting started...", "Url": "https://example.com/products/widget-basic", "Category": "Products", "Price": "49.00" } } ]' ``` ```bash US theme={null} curl -X PUT "https://api-us1.cludo.com/api/v4/{customerId}/index/{crawlerId}/documents" \ -H "Authorization: Basic {base64(customerId:apiKey)}" \ -H "Content-Type: application/json" \ -d '[ { "id": "product-123", "type": "PageContent", "fields": { "Title": "Widget Pro", "Description": "Our most popular widget...", "Url": "https://example.com/products/widget-pro", "Category": "Products", "Price": "99.00" } }, { "id": "product-456", "type": "FileContent", "fields": { "Title": "Widget Basic", "Description": "Great for getting started...", "Url": "https://example.com/products/widget-basic", "Category": "Products", "Price": "49.00" } } ]' ``` ### Partial update Update specific fields without replacing the entire document. The optional top-level `type` works the same way here as on replace — omit it to keep the existing kind, or send `"PageContent"` / `"FileContent"` to set it. ```bash EU theme={null} curl -X PATCH "https://api.cludo.com/api/v4/{customerId}/index/{crawlerId}/documents" \ -H "Authorization: Basic {base64(customerId:apiKey)}" \ -H "Content-Type: application/json" \ -d '[ { "id": "product-123", "fields": { "Price": "89.00" } } ]' ``` ```bash US theme={null} curl -X PATCH "https://api-us1.cludo.com/api/v4/{customerId}/index/{crawlerId}/documents" \ -H "Authorization: Basic {base64(customerId:apiKey)}" \ -H "Content-Type: application/json" \ -d '[ { "id": "product-123", "fields": { "Price": "89.00" } } ]' ``` ### Delete documents ```bash EU theme={null} # Single document curl -X DELETE "https://api.cludo.com/api/v4/{customerId}/index/{crawlerId}/documents?documentId=product-123" \ -H "Authorization: Basic {base64(customerId:apiKey)}" # Bulk delete by filter (filters are ANDed together) curl -X POST "https://api.cludo.com/api/v4/{customerId}/index/{crawlerId}/documents/bulk-delete" \ -H "Authorization: Basic {base64(customerId:apiKey)}" \ -H "Content-Type: application/json" \ -d '{ "Category": { "operator": "Eq", "values": ["Discontinued"] }, "Date_date": { "operator": "Lt", "values": ["2024/01/01"] } }' ``` ```bash US theme={null} # Single document curl -X DELETE "https://api-us1.cludo.com/api/v4/{customerId}/index/{crawlerId}/documents?documentId=product-123" \ -H "Authorization: Basic {base64(customerId:apiKey)}" # Bulk delete by filter (filters are ANDed together) curl -X POST "https://api-us1.cludo.com/api/v4/{customerId}/index/{crawlerId}/documents/bulk-delete" \ -H "Authorization: Basic {base64(customerId:apiKey)}" \ -H "Content-Type: application/json" \ -d '{ "Category": { "operator": "Eq", "values": ["Discontinued"] }, "Date_date": { "operator": "Lt", "values": ["2024/01/01"] } }' ``` *** ## Queue URLs for crawling Instead of pushing document fields directly, you can queue URLs for the crawler to fetch: ```bash EU theme={null} curl -X POST "https://api.cludo.com/api/v4/{customerId}/crawler/{crawlerId}/paths" \ -H "Authorization: Basic {base64(customerId:apiKey)}" \ -H "Content-Type: application/json" \ -d '[ "https://example.com/new-page", "https://example.com/updated-page" ]' ``` ```bash US theme={null} curl -X POST "https://api-us1.cludo.com/api/v4/{customerId}/crawler/{crawlerId}/paths" \ -H "Authorization: Basic {base64(customerId:apiKey)}" \ -H "Content-Type: application/json" \ -d '[ "https://example.com/new-page", "https://example.com/updated-page" ]' ``` # Introduction Source: https://docs.cludo.com/introduction Start here for the Cludo API: a unified reference covering search, autocomplete, AI answers, crawlers, indexing, and analytics across v3 and v4 endpoints. Cludo is a site search and AI platform for creating relevant search experiences across websites, help centers, and other digital content. This documentation covers the Cludo APIs for search, AI answers, crawlers, analytics, and search management tools. If you are not yet a Cludo customer, start with [cludo.com](https://www.cludo.com/) to learn about the platform or [contact sales](https://cludo.com/pricing/) to discuss your use case. If you already have access, sign in to [MyCludo](https://my.cludo.com) to find the credentials used throughout these docs. Make your first API call within a few minutes. Full endpoint index with version guidance. SiteKey and API Key (Basic) authentication. AI-powered search with semantic understanding. # Quickstart Source: https://docs.cludo.com/quickstart Make your first Cludo API search call in minutes by setting up authentication, picking your region, and running a sample query against an engine. This guide walks you through making your first search API call using the v4 API. **Prerequisites:** You need a Cludo account with at least one engine configured. Sign in to [MyCludo](https://my.cludo.com) to get your credentials. ## Step 1: Find your region Your region is determined by your **customer ID**: | Customer ID | Region | Base URL | | ---------------- | ------ | --------------------------- | | Below 10,000,000 | EU | `https://api.cludo.com` | | 10,000,000+ | US | `https://api-us1.cludo.com` | ## Step 2: Get your credentials Log in to [MyCludo API settings](https://my.cludo.com/settings/api-settings) and find the following values: | Value | Where to find it | | --------------- | ---------------------------------------- | | **Customer ID** | Dashboard → Account Settings | | **Engine ID** | Dashboard → Engines → select your engine | | **API Key** | MyCludo API settings | ## Step 3: Build your auth token Unless an endpoint says otherwise, use **Basic (API Key)** authentication for Cludo API requests: ```bash theme={null} # Format: base64(customerId:apiKey) echo -n "3:c8fk2L9mK4pQ" | base64 # Output: MzpjOGZrMkw5bUs0cFE= ``` **SiteKey authentication** is available for public-facing search where you do not want to expose your API key. See the [Authentication guide](/authentication) for SiteKey token format. ### Try it: build your token Use the tool below to generate a Basic or SiteKey authorization header and a ready-to-run cURL command. Basic authentication is the default choice unless you are building a public client-side search integration. ## Step 4: Make your first search Keep Basic API keys private. Use the Basic examples from a trusted backend, script, or local test. For browser code, use SiteKey authentication instead. ```bash cURL Basic (EU) theme={null} curl -X POST "https://api.cludo.com/api/v4/3/6/search" \ -H "Authorization: Basic MzpjOGZrMkw5bUs0cFE=" \ -H "Content-Type: application/json" \ -d '{ "query": "*", "page": 1, "perPage": 10 }' ``` ```bash cURL Basic (US) theme={null} curl -X POST "https://api-us1.cludo.com/api/v4/3/6/search" \ -H "Authorization: Basic MzpjOGZrMkw5bUs0cFE=" \ -H "Content-Type: application/json" \ -d '{ "query": "*", "page": 1, "perPage": 10 }' ``` ```bash cURL SiteKey (EU) theme={null} curl -X POST "https://api.cludo.com/api/v4/3/6/search" \ -H "Authorization: SiteKey Mzo2OlNlYXJjaEtleQ==" \ -H "Content-Type: application/json" \ -d '{ "query": "*", "page": 1, "perPage": 10 }' ``` ```python Python theme={null} import requests import base64 # Build Basic token: base64(customerId:apiKey) token = base64.b64encode(b"3:c8fk2L9mK4pQ").decode() # Use https://api-us1.cludo.com for US region url = "https://api.cludo.com/api/v4/3/6/search" headers = { "Authorization": f"Basic {token}", "Content-Type": "application/json" } payload = { "query": "*", "page": 1, "perPage": 10 } response = requests.post(url, json=payload, headers=headers) data = response.json() print(data) ``` ```typescript TypeScript theme={null} // Build Basic token: base64(customerId:apiKey) const token = btoa("3:c8fk2L9mK4pQ"); // Use https://api-us1.cludo.com for US region const response = await fetch("https://api.cludo.com/api/v4/3/6/search", { method: "POST", headers: { "Authorization": `Basic ${token}`, "Content-Type": "application/json", }, body: JSON.stringify({ query: "*", page: 1, perPage: 10, }), }); const data = await response.json(); console.log(data); ``` ```javascript JavaScript theme={null} // Build Basic token: base64(customerId:apiKey) const token = btoa("3:c8fk2L9mK4pQ"); // Use https://api-us1.cludo.com for US region fetch("https://api.cludo.com/api/v4/3/6/search", { method: "POST", headers: { "Authorization": `Basic ${token}`, "Content-Type": "application/json", }, body: JSON.stringify({ query: "*", page: 1, perPage: 10, }), }) .then((response) => response.json()) .then((data) => console.log(data)); ``` ## Step 5: Understand the response ```json theme={null} { "typedDocuments": [ { "fields": { "Title": "Getting Started Guide", "Description": "Learn how to set up Cludo search...", "Url": "https://example.com/getting-started" }, "highlight": { "Title": "Getting Started Guide" }, "id": "doc_123", "score": 15.7 } ], "totalDocument": 42, "facets": {}, "banners": [], "suggestions": [], "fixedQuery": null, "queryId": "abc-123-def", "generativeAnswerAvailable": true } ``` | Field | Description | | --------------------------- | -------------------------------------------------------- | | `typedDocuments` | Array of search results with field values and highlights | | `totalDocument` | Total number of matching documents | | `facets` | Facet counts for filtering | | `fixedQuery` | Spell-corrected query (if applicable) | | `queryId` | Unique identifier for this search request | | `generativeAnswerAvailable` | Whether AI Chat can answer this query | ## What's next? Complete search endpoint reference. Track searches and clicks. Push custom content to your search index. Manage banners, rankings, quicklinks, and synonyms. # Regions Source: https://docs.cludo.com/regions Cludo API regions and base URLs for US and EU deployments, plus how to identify which region hosts your account so requests reach the right endpoint. Requests sent to the wrong region return `401 Unauthorized` because credentials are validated against the regional account store. Always match the base URL to your customer ID range. Code examples throughout this documentation include EU and US tabs. Select your region to use the correct base URL. Cludo operates in two regions. Your region is determined by your **customer ID**: | Customer ID | Region | Base URL | | -------------------- | ------ | --------------------------- | | Below 10,000,000 | EU | `https://api.cludo.com` | | 10,000,000 and above | US | `https://api-us1.cludo.com` | You can find your customer ID in [MyCludo](https://my.cludo.com) under **Account Settings**. # Troubleshooting Source: https://docs.cludo.com/troubleshooting Diagnose common Cludo API issues including authentication failures, 401/403/404 errors, missing results, region mismatches, and indexing problems. This page covers common errors and pitfalls when integrating with the Cludo API. *** ## Authentication errors ### 401 Unauthorized **Common causes:** | Cause | Fix | | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Missing `Authorization` header | Add `Authorization: SiteKey {token}` or `Authorization: Basic {token}` | | Malformed base64 token | Verify your token encodes the correct format: `customerId:engineId:SearchKey` (SiteKey) or `customerId:apiKey` (Basic). Note: `SearchKey` is a fixed literal string. | | Wrong auth scheme for the endpoint | Index management, crawler URL queues, and search tools require Basic authentication. See [Authentication](/authentication). | | Wrong region | Verify that the base URL matches your customer ID range. See [Regions](/regions). | **Debugging tip:** Decode your base64 token to verify its contents: ```bash theme={null} echo "Mzo2OlNlYXJjaEtleQ==" | base64 --decode # Should output: 3:6:SearchKey ``` ### 403 Forbidden **Common causes:** | Cause | Fix | | ------------------------------------ | ------------------------------------------------------------------------------ | | SiteKey used for management endpoint | Use Basic (API Key) auth instead | | Engine does not belong to customer | Ensure the engine ID in your token matches an engine owned by the customer ID | | Feature is not enabled | For AI endpoints, confirm that AI Chat or AI Summary is enabled for the engine | *** ## Wrong region Requests sent to the wrong region return `401 Unauthorized` because credentials are validated against the regional account store. EU credentials are only valid on the EU base URL and US credentials are only valid on the US base URL. **Fix:** 1. Check your customer ID: * Below 10,000,000 → EU: `https://api.cludo.com` * 10,000,000 and above → US: `https://api-us1.cludo.com` 2. Update the request base URL to match the customer ID range. See [Regions](/regions) for full details. *** ## Search returns no results **Symptom:** Search returns `totalDocument: 0` even though content exists. **Common causes:** | Cause | Fix | | ---------------------------- | ------------------------------------------------------------------------------------ | | Wrong engine ID | Verify your engine ID in Dashboard → Engines | | Content not yet indexed | Check crawl status in Dashboard → Crawlers. New content may take minutes to appear. | | Filters too restrictive | Remove filters temporarily to confirm the query itself returns results | | Wrong field names in filters | Field names are case-sensitive. Check available fields in your engine configuration. | *** ## AI Chat / AI Summary errors These errors are specific to the AI Chat (`/search/answer`) and AI Summary (`/search/summarize`) endpoints. ### 403 Forbidden: "AiChat feature is not enabled" AI Chat and AI Summary return `403 Forbidden` when the respective feature is not enabled for the engine. **Fix:** The AI feature must be enabled for your engine. Contact support or check your engine configuration in [MyCludo](https://my.cludo.com). ### 422 Unprocessable Entity from AI Summary AI Summary returns `422 Unprocessable Entity` when the request is well-formed and reaches the model, but the selected search results do not contain enough relevant context to generate a useful summary. Treat this as a completed request with no usable answer. Show a "no summary available" message instead of retrying immediately, then consider broadening the query, selecting more relevant sources, or checking whether the indexed content covers the topic. ### AI returns no answer or a generic answer The `generativeAnswerAvailable` field in the search response indicates whether AI can attempt an answer. If it returns `false`, AI will not generate a useful response. **Common causes:** | Cause | Fix | | --------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Query is too vague | Use specific, descriptive questions | | Relevant content is not indexed | The page may exist on your website but not in the search index. Use the crawler URL test in MyCludo to verify. See [Content indexing issues](#content-indexing-issues). | | Crawler cannot access the content | The crawler may be blocked, the page may require JavaScript rendering, or the page may be excluded by crawler rules | | Pushed content is incomplete | Ensure pushed documents include enough title, URL, and body/description content for AI to ground an answer | | Canned response matched instead | Canned responses are checked before AI is invoked. Review your canned response configuration in [MyCludo](https://my.cludo.com) | *** ## Content indexing issues ### Pushed documents don't appear in search **Symptom:** Documents pushed via Index Management don't appear in search results. **Common causes:** | Cause | Fix | | ----------------------- | ------------------------------------------------------------------------------------------------------------------------ | | Wrong crawler ID | Verify the crawler id in Dashboard → Engines. A crawler ID that does not exist for the customer returns `404 Not Found`. | | Missing required fields | Check [Index Management](/api-reference/v4/content/index-management) for field requirements. | | Document URL conflicts | If a document with the same URL already exists, it may need to be replaced (PUT) not appended | ### Crawled pages don't appear in search If website pages aren't being indexed, use the **Test Crawler** feature in MyCludo to diagnose why. **How to use Test Crawler:** 1. Log in to [MyCludo](https://my.cludo.com) 2. Navigate to **Crawlers** and select your crawler 3. Click the **Test Crawler** button 4. Enter the URL you want to test and press Enter **What Test Crawler shows you:** | Result | Meaning | | ----------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | | **Success** | The crawler can fetch and parse the page. Check the extracted fields to verify content is being captured correctly. | | **Blocked by robots.txt** | The page is disallowed in robots.txt. Update robots.txt or configure the crawler to ignore it. | | **HTTP error (4xx/5xx)** | The page returned an error. Verify the URL is accessible in a browser. | | **No content extracted** | The page loaded but no indexable content was found. The content may require JavaScript rendering or may be in elements the crawler doesn't extract. | | **Excluded by crawler rules** | The URL matches an exclusion pattern in your crawler configuration. Review your include/exclude rules. | | **Redirect** | The URL redirects to another page. Consider using the final URL instead. | **Common issues Test Crawler helps identify:** * **JavaScript-rendered content**: If your page content loads via JavaScript. Ask Cludo Support or Account Manager to enable JavaScript rendering in crawler settings * **Login-protected pages**: The crawler cannot access pages behind authentication * **Slow-loading pages**: Pages that take too long to load may time out * **Missing Crawler Fields**: Verify the page has title and description for the crawler to extract *** ## Analytics not showing data **Symptom:** The analytics dashboard shows no data even though searches are happening. **Fix:** Add the [Cludo API analytics script](https://help.cludo.com/analytics/) or send tracking events through the API. If you build your own search UI, record both query events and result click events so analytics can connect searches to user behavior. *** ## Rate limiting **Symptom:** API returns `429 Too Many Requests`. **Fix:** Reduce your request rate. If you need higher limits, contact [support@cludo.com](mailto:support@cludo.com). *** ## CORS errors **Symptom:** Browser console shows CORS errors when calling the API from client-side code. **Fix:** Browser-based integrations should use SiteKey for search-related endpoints or anonymous requests for tracking. Do not expose Basic API keys in client-side code. If you see CORS errors: 1. Verify you're using SiteKey auth (not Basic) for client-side calls 2. Ensure the `Authorization` header is correctly formatted 3. Check that you're hitting the correct base URL for your region 4. Move server-only calls, such as index management and search tools, behind your own backend *** ## Still stuck? If none of the above resolves your issue: 1. Check the [FAQ](/faq) for answers to common questions 2. Email [support@cludo.com](mailto:support@cludo.com) with: * Your customer ID and engine ID * The endpoint you're calling * The full request (headers + body) * The full response (status code + body)