# Get category page results
Source: https://docs.doofinder.com/api-reference/category-merchandising/get-category-page-results
/openapi/category-merchandising-v1.yaml get /category_merchandising/{hashid}
Returns search results for the category page whose URL pattern matches the provided `url`.
The `url` is matched against the URL patterns configured for the given search engine.
The highest-priority matching pattern determines the base filter and facets applied to
the search. Client-supplied `filter` params are merged on top: keys that overlap with
the pattern filter are ignored, the rest are added to the query.
**Sort order:** If `sort` params are provided they take precedence. Otherwise, the sort
configured in the category page settings is applied. If neither is configured, results
are returned in the engine's default order.
# Clicked item searches
Source: https://docs.doofinder.com/api-reference/clicks-&-interactions/clicked-item-searches
/openapi/stats-v2.yaml get /api/v2/stats/clicked_items/searches
Gets the most common searched for a clicked item, and how many times it has been clicked from those searches.
# Clicked items
Source: https://docs.doofinder.com/api-reference/clicks-&-interactions/clicked-items
/openapi/stats-v2.yaml get /api/v2/stats/clicked_items
Gets the most commonly clicked items in a time period.
# Clicks
Source: https://docs.doofinder.com/api-reference/clicks-&-interactions/clicks
/openapi/stats-v2.yaml get /api/v2/stats/clicks
Counts number of clicks in a time period grouped by day.
# Clicks items and position
Source: https://docs.doofinder.com/api-reference/clicks-&-interactions/clicks-items-and-position
/openapi/stats-v2.yaml get /api/v2/stats/clicked_items/position
Gets the number of clicks each clicked product had in a period of time grouped by position.
# Clicks with users
Source: https://docs.doofinder.com/api-reference/clicks-&-interactions/clicks-with-users
/openapi/stats-v2.yaml get /api/v2/stats/clicks/users
Counts numbers of different users and products in clicks for a time period.
# Redirections
Source: https://docs.doofinder.com/api-reference/clicks-&-interactions/redirections
/openapi/stats-v2.yaml get /api/v2/stats/redirects
Gets redirections and how many times users make use of them in a time period.
# Checkout cart process
Source: https://docs.doofinder.com/api-reference/conversions-&-sales/checkout-cart-process
/openapi/stats-v2.yaml post /api/v2/stats/carts
Process checkout cart information on Doofinder statistics.
# Checkouts
Source: https://docs.doofinder.com/api-reference/conversions-&-sales/checkouts
/openapi/stats-v2.yaml get /api/v2/stats/checkouts
Counts numbers of checkouts in a time period grouped by day.
# Get top sales
Source: https://docs.doofinder.com/api-reference/conversions-&-sales/get-top-sales
/openapi/stats-v2.yaml get /api/v2/stats/top-sales
Gets the top sold items in a period.
# Sale confirm
Source: https://docs.doofinder.com/api-reference/conversions-&-sales/sale-confirm
/openapi/stats-v2.yaml post /api/v2/stats/sales
Register checkout event.
# Sales
Source: https://docs.doofinder.com/api-reference/conversions-&-sales/sales
/openapi/stats-v2.yaml get /api/v2/stats/sales
Gets the total price for sales checkouts in a period, where a session id identifies every sale.
# Banners
Source: https://docs.doofinder.com/api-reference/features/banners
/openapi/stats-v2.yaml get /api/v2/stats/banners
Gets how many times banners have been displayed and clicked in a time period, grouped by banner id.
# Custom results
Source: https://docs.doofinder.com/api-reference/features/custom-results
/openapi/stats-v2.yaml get /api/v2/stats/custom-results
Gets how many times custom results have been displayed and clicked in a time period, grouped by custom result id.
# Facets
Source: https://docs.doofinder.com/api-reference/features/facets
/openapi/stats-v2.yaml get /api/v2/stats/facets
Gets how many times facets filters have been used in a time period, grouped by facet field.
# Facets by day
Source: https://docs.doofinder.com/api-reference/features/facets-by-day
/openapi/stats-v2.yaml get /api/v2/stats/facets_by_day
Gets how many times facets filters have been used in a time period, grouped by day.
# Sector
Source: https://docs.doofinder.com/api-reference/features/sector
/openapi/stats-v2.yaml get /api/v2/stats/sector/{name}
Retrieve the median of the metric you send for the sector and/or the hashid.
# Top facets values
Source: https://docs.doofinder.com/api-reference/features/top-facets-values
/openapi/stats-v2.yaml get /api/v2/stats/facets/top
Gets most common facets filters used, how many times they have been used and which filter has been applied in a time period.
# Visit stats
Source: https://docs.doofinder.com/api-reference/features/visit-stats
/openapi/stats-v2.yaml post /api/v2/stats/visit
Save visit event on Doofinder statistics
# Create
Source: https://docs.doofinder.com/api-reference/indices/create
/openapi/management-v2.yaml post /api/v2/search_engines/{hashid}/indices
Creates a new index for a search engine.
# Create temporary index
Source: https://docs.doofinder.com/api-reference/indices/create-temporary-index
/openapi/management-v2.yaml post /api/v2/search_engines/{hashid}/indices/{name}/temp/
Creates a new empty temporary index for the same index name. There can
not be two temporary indices at the same time, so any request made to
this endpoint when there is one created will fail. Creating a temporary
index also sets a lock preventing any changes on the search engine until
the temporary index is deleted.
# Delete
Source: https://docs.doofinder.com/api-reference/indices/delete
/openapi/management-v2.yaml delete /api/v2/search_engines/{hashid}/indices/{name}
Deletes a search engine index.
# Delete temporary index
Source: https://docs.doofinder.com/api-reference/indices/delete-temporary-index
/openapi/management-v2.yaml delete /api/v2/search_engines/{hashid}/indices/{name}/temp/
Deletes the temporary index. This also removes the lock in the search
engine. If there is no temporary index this will return a 404 (Not found).
# Get
Source: https://docs.doofinder.com/api-reference/indices/get
/openapi/management-v2.yaml get /api/v2/search_engines/{hashid}/indices/{name}
Gets a search engine index.
# List
Source: https://docs.doofinder.com/api-reference/indices/list
/openapi/management-v2.yaml get /api/v2/search_engines/{hashid}/indices
List all indices of search engine.
# Reindex into temporary index
Source: https://docs.doofinder.com/api-reference/indices/reindex-into-temporary-index
/openapi/management-v2.yaml post /api/v2/search_engines/{hashid}/indices/{name}/_reindex_to_temp/
This executes a reindexing operation between the real index and the
temporary one. It reads all items from the real and index them onto the
temporary.
This will return a 404 (Not found) if there is no temporary index.
# Reindexing task status
Source: https://docs.doofinder.com/api-reference/indices/reindexing-task-status
/openapi/management-v2.yaml get /api/v2/search_engines/{hashid}/indices/{name}/_reindex_to_temp/
Returns the status of the last scheduled reindexing tasks. If there is
none, or the task finished more than 24 hours ago, it will return a 404 error.
# Replace indices
Source: https://docs.doofinder.com/api-reference/indices/replace-indices
/openapi/management-v2.yaml post /api/v2/search_engines/{hashid}/indices/{name}/_replace_by_temp/
Replaces the content of the current "production" index with the content
of the temporary one.
# Update
Source: https://docs.doofinder.com/api-reference/indices/update
/openapi/management-v2.yaml patch /api/v2/search_engines/{hashid}/indices/{name}
Updates a search engine index.
# Create
Source: https://docs.doofinder.com/api-reference/items/create
/openapi/management-v2.yaml post /api/v2/search_engines/{hashid}/indices/{name}/items/
Creates an item in the index with the data provided.
# Create in bulk
Source: https://docs.doofinder.com/api-reference/items/create-in-bulk
/openapi/management-v2.yaml post /api/v2/search_engines/{hashid}/indices/{name}/items/_bulk
Creates a list of items in the index in a single bulk operation.
# Create in bulk in temporal
Source: https://docs.doofinder.com/api-reference/items/create-in-bulk-in-temporal
/openapi/management-v2.yaml post /api/v2/search_engines/{hashid}/indices/{name}/temp/items/_bulk
Creates a list of items in the temporal index in a single bulk operation.
# Create in temporal
Source: https://docs.doofinder.com/api-reference/items/create-in-temporal
/openapi/management-v2.yaml post /api/v2/search_engines/{hashid}/indices/{name}/temp/items/
Creates an item with the data provided in the temporal index.
# Delete
Source: https://docs.doofinder.com/api-reference/items/delete
/openapi/management-v2.yaml delete /api/v2/search_engines/{hashid}/indices/{name}/items/{item_id}
Deletes item from the index by its id.
# Delete from temporal
Source: https://docs.doofinder.com/api-reference/items/delete-from-temporal
/openapi/management-v2.yaml delete /api/v2/search_engines/{hashid}/indices/{name}/temp/items/{item_id}
Deletes an item from the temporal index given its id.
# Delete in bulk
Source: https://docs.doofinder.com/api-reference/items/delete-in-bulk
/openapi/management-v2.yaml delete /api/v2/search_engines/{hashid}/indices/{name}/items/_bulk
Deletes a list of items from the index in a single bulk operation.
# Delete in bulk from temporal
Source: https://docs.doofinder.com/api-reference/items/delete-in-bulk-from-temporal
/openapi/management-v2.yaml delete /api/v2/search_engines/{hashid}/indices/{name}/temp/items/_bulk
Deletes a list of items in the temporal index in a single bulk operation.
# Find by ids
Source: https://docs.doofinder.com/api-reference/items/find-by-ids
/openapi/management-v2.yaml post /api/v2/search_engines/{hashid}/indices/{name}/items/_mget
Finds a list items in a single operation by a list of ids.
# Find by ids from temporal
Source: https://docs.doofinder.com/api-reference/items/find-by-ids-from-temporal
/openapi/management-v2.yaml post /api/v2/search_engines/{hashid}/indices/{name}/temp/items/_mget
Finds a list items from a temporal index in a single operation by a list of ids.
# Get
Source: https://docs.doofinder.com/api-reference/items/get
/openapi/management-v2.yaml get /api/v2/search_engines/{hashid}/indices/{name}/items/{item_id}
Gets an item from the index by its id.
# Get from temporal
Source: https://docs.doofinder.com/api-reference/items/get-from-temporal
/openapi/management-v2.yaml get /api/v2/search_engines/{hashid}/indices/{name}/temp/items/{item_id}
Gets an item from the temporal index by its id.
# Items count
Source: https://docs.doofinder.com/api-reference/items/items-count
/openapi/management-v2.yaml get /api/v2/search_engines/{hashid}/indices/{name}/items/_count
Returns the total number of items in an index.
# Scroll index
Source: https://docs.doofinder.com/api-reference/items/scroll-index
/openapi/management-v2.yaml get /api/v2/search_engines/{hashid}/indices/{name}/items/
Scrolls through all the items of an index. The first request starts the scroll and generate a scroll id that can be traversed with each successive requests. There is a limited time period on which the traverse is possible. After 5 minutes the scroll expires and it is no longer accesible, a new request should be made to traverse items again from the beginning.
# Update
Source: https://docs.doofinder.com/api-reference/items/update
/openapi/management-v2.yaml patch /api/v2/search_engines/{hashid}/indices/{name}/items/{item_id}
Partially updates item from index by its id. The operation returns the updated item.
# Update from temporal
Source: https://docs.doofinder.com/api-reference/items/update-from-temporal
/openapi/management-v2.yaml patch /api/v2/search_engines/{hashid}/indices/{name}/temp/items/{item_id}
Partially updates an item in the temporal index given its id. The operation will return the updated item.
# Update in bulk
Source: https://docs.doofinder.com/api-reference/items/update-in-bulk
/openapi/management-v2.yaml patch /api/v2/search_engines/{hashid}/indices/{name}/items/_bulk
Updates a list of items from the index in a single bulk operation.
# Update in bulk from temporal
Source: https://docs.doofinder.com/api-reference/items/update-in-bulk-from-temporal
/openapi/management-v2.yaml patch /api/v2/search_engines/{hashid}/indices/{name}/temp/items/_bulk
Updates a list of items in the temporal index in a single bulk operation.
# Get widget recommendations
Source: https://docs.doofinder.com/api-reference/recommendations/get-widget-recommendations
/openapi/recommendations-v1.yaml post /api/widget/{widget_id}
Retrieves personalized recommendations for a specific widget
# Create
Source: https://docs.doofinder.com/api-reference/search-engines/create
/openapi/management-v2.yaml post /api/v2/search_engines
Creates a new search engine with the provided data. It is not possible to run searches against the new search engine as it does not have any index yet. You must create an index belonging to the new search engine to be able to make searches.
# Delete
Source: https://docs.doofinder.com/api-reference/search-engines/delete
/openapi/management-v2.yaml delete /api/v2/search_engines/{hashid}
Deletes a search engine.
# Get
Source: https://docs.doofinder.com/api-reference/search-engines/get
/openapi/management-v2.yaml get /api/v2/search_engines/{hashid}
Gets a search engine details.
# Get process task status
Source: https://docs.doofinder.com/api-reference/search-engines/get-process-task-status
/openapi/management-v2.yaml get /api/v2/search_engines/{hashid}/_process
Gets the status of the last process task. Status persists for 72 hours. If there is no recent task, it will return an error.
# List
Source: https://docs.doofinder.com/api-reference/search-engines/list
/openapi/management-v2.yaml get /api/v2/search_engines
Lists all user's search engines.
# Process
Source: https://docs.doofinder.com/api-reference/search-engines/process
/openapi/management-v2.yaml post /api/v2/search_engines/{hashid}/_process
Schedules a task for processing all search engine's data sources.
# Update
Source: https://docs.doofinder.com/api-reference/search-engines/update
/openapi/management-v2.yaml patch /api/v2/search_engines/{hashid}
Updates a search engine.
# Image Search
Source: https://docs.doofinder.com/api-reference/search/image-search
/openapi/search-v6.yaml post /6/{hashid}/_image_search
Search through indexed images of a search engine.
# Search query
Source: https://docs.doofinder.com/api-reference/search/search-query
/openapi/search-v6.yaml get /6/{hashid}/_search
Search through indexed items of a search engine.
# Search query (POST)
Source: https://docs.doofinder.com/api-reference/search/search-query-post
/openapi/search-v6.yaml post /6/{hashid}/_search
Search through indexed items of a search engine.
Identical to the GET variant but accepts parameters as a JSON body,
which is useful when query strings would be too long or when sending
complex nested structures (filters, facets, sort).
# Suggestions
Source: https://docs.doofinder.com/api-reference/search/suggestions
/openapi/search-v6.yaml get /6/{hashid}/_suggest
Search through indexed suggestions of a search engine.
# Visually Similar
Source: https://docs.doofinder.com/api-reference/search/visually-similar
/openapi/search-v6.yaml get /6/{hashid}/_visually_similar
Search for elements visually similar to the given dfid.
# Popular searches
Source: https://docs.doofinder.com/api-reference/searches/popular-searches
/openapi/stats-v2.yaml get /api/v2/stats/searches/popular
Gets the most popular searches (the ones containing most clicked items) in a time period.
# Results searches
Source: https://docs.doofinder.com/api-reference/searches/results-searches
/openapi/stats-v2.yaml get /api/v2/stats/results/top
Gets the most commonly `metric` obtained in searches during a time period. Where `metric` can be brand or categories.
# Searches
Source: https://docs.doofinder.com/api-reference/searches/searches
/openapi/stats-v2.yaml get /api/v2/stats/searches
Counts number of searches in a time period grouped by day.
# Searches locations
Source: https://docs.doofinder.com/api-reference/searches/searches-locations
/openapi/stats-v2.yaml get /api/v2/stats/searches/locations
Gets all searches locations for a time period.
# Top searches
Source: https://docs.doofinder.com/api-reference/searches/top-searches
/openapi/stats-v2.yaml get /api/v2/stats/searches/top
Gets a list of the most common searches in a time period.
# Add to cart
Source: https://docs.doofinder.com/api-reference/session-&-events/add-to-cart
/openapi/search-v6.yaml put /6/{hashid}/stats/cart/{session_id}
Registers a click event on the cart.
# Click stats
Source: https://docs.doofinder.com/api-reference/session-&-events/click-stats
/openapi/search-v6.yaml put /6/{hashid}/stats/click
Save click event on doofinder statistics
# Init session
Source: https://docs.doofinder.com/api-reference/session-&-events/init-session
/openapi/search-v6.yaml put /6/{hashid}/stats/init
Starts a session identified by a session_id. The session is used to
"group" events. I.e. it groups user interactions during a session.
Like clicking some banner images, or completing a checkout.
# Logs a banner image click
Source: https://docs.doofinder.com/api-reference/session-&-events/logs-a-banner-image-click
/openapi/search-v6.yaml put /6/{hashid}/stats/image
Logs a "click on banner image" event in stats logs.
# Logs a checkout
Source: https://docs.doofinder.com/api-reference/session-&-events/logs-a-checkout
/openapi/search-v6.yaml put /6/{hashid}/stats/checkout
Logs a checkout event in stats logs. That is the event for when a
customer complete a checkout. The info of the items that were in
her session when she completes the checkout are logged in the event.
# Logs a redirection
Source: https://docs.doofinder.com/api-reference/session-&-events/logs-a-redirection
/openapi/search-v6.yaml put /6/{hashid}/stats/redirect
Logs a "redirection triggered" event in stats logs.
# Inits with users
Source: https://docs.doofinder.com/api-reference/usage-&-sessions/inits-with-users
/openapi/stats-v2.yaml get /api/v2/stats/inits/users
Counts numbers of different users in sessions for a time period.
# Search engine usage
Source: https://docs.doofinder.com/api-reference/usage-&-sessions/search-engine-usage
/openapi/stats-v2.yaml get /api/v2/stats/search_engine_users
Gets how many visits a Search engine receive and from that users how many inits & searches in a time period
# Sessions
Source: https://docs.doofinder.com/api-reference/usage-&-sessions/sessions
/openapi/stats-v2.yaml get /api/v2/stats/inits
Counts number of total unique search sessions in a time period group by day.
# Sessions geolocation
Source: https://docs.doofinder.com/api-reference/usage-&-sessions/sessions-geolocation
/openapi/stats-v2.yaml get /api/v2/stats/inits/locations
Gets all sessions geolocation for a time period.
# Usage
Source: https://docs.doofinder.com/api-reference/usage-&-sessions/usage
/openapi/stats-v2.yaml get /api/v2/stats/usage
Gets the usage of a list of search engines during a period.
It sums the query and API requests made to the service.
Since usage is computed in UTC time, there is no need to specify the
timezone in this endpoint.
# Category Merchandising API
Source: https://docs.doofinder.com/category-merchandising/overview
Retrieve search results for category listing pages, with URL-pattern-driven filtering and merchandising rules applied.
The Category Merchandising API powers category listing pages (PLPs) on your ecommerce site. It matches the current page URL against patterns you've configured in the Admin Panel, applies the corresponding product filter, and returns a paginated, faceted result set — with your merchandising rules (pinning, boosting, hiding, sort order) already applied.
**Version:** 1.0
## Base URL
```
https://{zone}-category-merchandising.doofinder.com/api/1
```
Supported zones: `eu1`, `us1`, `ap1`
## Authentication
```http theme={null}
Authorization: Token {your_token}
```
The token is validated against the account owning the search engine identified by `hashid`. A missing, invalid, or unauthorized token returns `401 Unauthorized`.
***
## How It Works
Go to **Category Merchandising → Pages** and create URL patterns for your category pages (e.g. `https://shop.example.com/categories/shoes*`). Assign a product filter to each pattern (e.g. `category = shoes`).
Send `GET /category_merchandising/{hashid}?url={current_page_url}`. The API matches the URL against your patterns and applies the correct filter automatically.
The response contains a paginated `results` array, `facets` for filter UI, the `base_filter` showing which rule matched, and an optional promotional `banner`.
***
## Endpoint
```
GET https://{zone}-category-merchandising.doofinder.com/api/1/category_merchandising/{hashid}
```
### Required parameters
| Parameter | Description |
| --------- | ------------------------------------------------------------------------------------------------------------------------ |
| `hashid` | Your search engine ID (path parameter). |
| `url` | Full URL of the current category page (query parameter). Query string and fragment are stripped before pattern matching. |
### Optional parameters
| Parameter | Default | Description |
| --------------------------------- | --------------- | ------------------------------------------------------------------------------------------------ |
| `page` | `1` | Page number (1-indexed). |
| `rpp` | `50` | Results per page. |
| `currency` | — | ISO 4217 code (e.g. `EUR`). Converts prices using exchange rates from your search engine config. |
| `sort[N][field]` | category config | Sort criteria. Overrides the sort configured for the category page. |
| `filter[field][]` | — | Additional filters on top of the URL pattern filter. Conflicting keys are silently ignored. |
| `exclude[field][]` | — | Exclude items with specific field values. |
| `results_personalization_dfids[]` | — | `dfid` values of recently-interacted items. Re-ranks results for contextual relevance. |
***
## Example Request
```bash theme={null}
curl "https://eu1-category-merchandising.doofinder.com/api/1/category_merchandising/d8fdeab7fce96a19d3fc7b0ca7a1e98b?url=https://shop.example.com/categories/shoes.html&rpp=24&filter[brand][]=Nike" \
-H "Authorization: Token ab46030xza33960aac71a10248489b6c26172f07"
```
## Example Response
```json theme={null}
{
"results": [
{
"dfid": "abc1234de@product@a1b2c3",
"id": "SKU-001",
"title": "Running Shoes Model X",
"price": 99.99,
"url": "https://shop.example.com/products/sku-001",
"image_url": "https://shop.example.com/images/sku-001.jpg"
}
],
"total": 243,
"page": 1,
"rpp": 24,
"base_filter": [
{ "field": "category", "values": ["shoes"] }
],
"filter": [
{ "field": "brand", "values": ["Nike"] }
],
"facets": {
"brand": {
"_type": "terms",
"buckets": [
{ "key": "Nike", "doc_count": 42 },
{ "key": "Adidas", "doc_count": 38 }
]
},
"price": {
"_type": "range",
"buckets": [
{ "stats": { "min": 9.99, "max": 499.99, "avg": 89.5 } }
]
}
},
"banner": {
"id": "189523",
"image": "https://shop.example.com/banners/shoes-banner.jpg",
"mobile_image": "https://shop.example.com/banners/shoes-banner-mobile.jpg",
"html_code": null,
"link": "https://shop.example.com/sale/shoes",
"target_blank": true
}
}
```
***
## Key Concepts
### URL pattern matching
The API evaluates the provided `url` against all active patterns for the search engine, ordered by **priority** (lowest number = highest priority). The first match determines:
* The **base filter** applied to all results (e.g. `category = shoes`)
* The configured **facets** to return
* The default **sort order**
If no pattern matches, or the matched category page is inactive, the API returns `404 Not Found`.
### Base filter vs. client filter
| | `base_filter` | `filter` |
| ---------------------- | --------------------- | ---------------------------------------- |
| **Source** | Matched URL pattern | Caller-supplied `filter[field][]` params |
| **Can be overridden?** | No | Yes — add or remove at call time |
| **Appears in facets?** | No — locked dimension | Yes |
Fields used by `base_filter` are excluded from the `facets` response. This prevents the UI from offering a filter that can't be changed (e.g. showing a "category" facet on a category page).
### Facet types
| Type | Description | Render as |
| ------- | ----------------------------------- | ------------- |
| `terms` | Discrete keyword values with counts | Checkbox list |
| `range` | Numeric min/max/avg stats | Price slider |
### Banner
If a promotional banner is configured for the matched category in the Admin Panel, it appears in the `banner` field. Use `html_code` when present (takes precedence over `image`); fall back to `image` / `mobile_image` otherwise.
***
## Error Responses
| Status | Description |
| ------ | --------------------------------------------------------- |
| `400` | `url` parameter is missing |
| `401` | Authorization header is missing, invalid, or unauthorized |
| `404` | No active URL pattern matches the provided `url` |
| `502` | Upstream search engine error |
# Doofinder API Reference
Source: https://docs.doofinder.com/index
Complete reference for the Doofinder suite of APIs. Build powerful search experiences, manage your data, and unlock analytics insights.
# References
Doofinder provides a suite of APIs to power search, personalization, and analytics for your ecommerce site.
Get your first API call running in under 5 minutes.
Query indexed items, get autocomplete suggestions, run image search, and log user interactions in real time.
Create and configure search engines, manage indices, and push or update items programmatically.
Retrieve analytics — sessions, top searches, click-through rates, conversion data, and more.
Deliver personalized product recommendations powered by Doofinder's recommendation engine.
Configure and manage category-level search rules and boost strategies.
## Architecture Overview
All Doofinder APIs are region-scoped. Your **search zone** determines the hostname to use:
| Zone | Region | Base domain |
| ----- | ------------- | --------------------- |
| `eu1` | Europe | `eu1-*.doofinder.com` |
| `us1` | United States | `us1-*.doofinder.com` |
| `ap1` | Asia Pacific | `ap1-*.doofinder.com` |
Each API uses a different subdomain pattern:
| API | Base URL |
| ---------------------- | ----------------------------------------------------- |
| Search API | `https://{zone}-search.doofinder.com` |
| Management API | `https://{zone}-api.doofinder.com` |
| Stats API | `https://{zone}-api.doofinder.com` |
| Recommendations API | `https://{zone}-recommendations.doofinder.com` |
| Category Merchandising | `https://{zone}-category-merchandising.doofinder.com` |
Your search zone is shown in the [Doofinder Admin Panel](https://admin.doofinder.com). The zone prefix on API keys (e.g. `eu1-ab46030x...`) is optional — the zone is determined by the hostname you call.
## Authentication at a Glance
All APIs authenticate via an `Authorization` HTTP header. The format depends on the API:
```bash Search API theme={null}
curl "https://eu1-search.doofinder.com/6/{hashid}/_search?query=shoes" \
-H "Authorization: Token eu1-ab46030xza33960aac71a10248489b6c26172f07"
```
```bash Management & Stats API theme={null}
curl "https://eu1-api.doofinder.com/api/v2/search_engines" \
-H "Authorization: Token ab46030xza33960aac71a10248489b6c26172f07"
```
```bash Recommendations API theme={null}
# No Authorization header required — widget ID acts as the credential
curl -X POST "https://eu1-recommendations.doofinder.com/api/widget/{widget_id}" \
-H "Content-Type: application/json" \
-d '{"current_url": "https://shop.example.com/products/shoes"}'
```
See the full [Authentication guide](/introduction/authentication) for JWT tokens and zone-specific key formats.
## Common Error Codes
| Code | Meaning |
| ----- | --------------------------------------------------- |
| `400` | Bad Request — invalid parameters |
| `401` | Unauthorized — missing or invalid API key |
| `403` | Forbidden — access denied (IP or origin blocked) |
| `404` | Not Found — resource does not exist |
| `413` | Payload Too Large — request body exceeds 8 MB |
| `422` | Unprocessable Entity — batch size exceeds 100 items |
| `429` | Too Many Requests — rate limit exceeded (20 req/s) |
See the [Error Reference](/introduction/errors) for full details.
# Authentication
Source: https://docs.doofinder.com/introduction/authentication
How to authenticate with Doofinder APIs.
All Doofinder APIs require authentication via the `Authorization` HTTP header. The exact format and key type vary by API.
## API Keys
Generate an API key in the [Doofinder Admin Panel](https://admin.doofinder.com/admin/account/api) under **Account → API Keys**. One key covers all APIs — Search, Management, and Stats.
Only the API key of the **account owner** is valid for API operations. Keys generated by team members will not work.
### Key format
The same key works across all APIs. You may see it written with a zone prefix (e.g. `eu1-ab46030x...`) — this prefix is optional and ignored by the API. Both formats are valid:
```
eu1-ab46030xza33960aac71a10248489b6c26172f07 ← zone prefix included (optional)
ab46030xza33960aac71a10248489b6c26172f07 ← no prefix (also valid)
```
The zone that serves your request is determined by the **hostname** you call, not by the key.
***
## Token Authentication
Pass the API key in the `Authorization` header as a `Token`:
```bash Search API theme={null}
curl "https://eu1-search.doofinder.com/6/{hashid}/_search?query=shoes" \
-H "Authorization: Token eu1-ab46030xza33960aac71a10248489b6c26172f07"
```
```bash Management API theme={null}
curl "https://eu1-api.doofinder.com/api/v2/search_engines" \
-H "Authorization: Token ab46030xza33960aac71a10248489b6c26172f07"
```
```bash Stats API theme={null}
curl "https://eu1-api.doofinder.com/api/v2/stats/searches" \
-H "Authorization: Token ab46030xza33960aac71a10248489b6c26172f07"
```
***
## JWT Authentication
The Management API and Stats API also support [JSON Web Tokens](https://jwt.io) (JWT) as an alternative to static API keys. JWTs are useful when you need short-lived credentials or want to avoid embedding long-lived secrets in client code.
### Required JWT claims
| Claim | Description |
| ------ | ---------------------------------------------------------------------------------------------- |
| `iat` | Issued At — Unix timestamp of when the token was created |
| `exp` | Expiration Time — Unix timestamp when the token expires. Must be within **one week** of `iat`. |
| `name` | Your Doofinder user code — find it in your Admin Panel profile |
### Signing
Sign the JWT with your **API management key** using the `HS256` algorithm.
### Usage
Send the JWT in the `Authorization` header as a `Bearer` token:
```bash theme={null}
curl "https://eu1-api.doofinder.com/api/v2/search_engines" \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoidGVzdCIsImlhdCI6MTUxNjIzOTAyMiwiZXhwIjoxNTE2ODQ1ODIyfQ.xxxxx"
```
```python Python (PyJWT) theme={null}
import jwt
import time
payload = {
"name": "your-user-code",
"iat": int(time.time()),
"exp": int(time.time()) + 3600 # 1 hour
}
token = jwt.encode(payload, "your-api-management-key", algorithm="HS256")
headers = {"Authorization": f"Bearer {token}"}
```
```javascript JavaScript (jsonwebtoken) theme={null}
const jwt = require("jsonwebtoken");
const token = jwt.sign(
{ name: "your-user-code" },
"your-api-management-key",
{ algorithm: "HS256", expiresIn: "1h" }
);
const headers = { Authorization: `Bearer ${token}` };
```
***
## Recommendations API
The Recommendations API does not use the `Authorization` header. The **widget ID** (a UUID) serves as the credential and is passed directly in the URL path:
```bash theme={null}
curl -X POST "https://eu1-recommendations.doofinder.com/api/widget/123e4567-e89b-12d3-a456-426614174000" \
-H "Content-Type: application/json" \
-d '{"current_url": "https://shop.example.com/products/shoes"}'
```
CORS is enforced on the Recommendations API. The `Origin` and `Referer` headers must match a domain configured in your store settings, or requests will be rejected with `403 Forbidden Origin`.
***
## Service zones
Your Doofinder account is assigned to a specific zone. All API calls must go to the correct zone hostname:
| Zone | Search API | Management & Stats API | Recommendations API | Category Merchandising |
| ----- | -------------------------- | ----------------------- | ----------------------------------- | ------------------------------------------ |
| `eu1` | `eu1-search.doofinder.com` | `eu1-api.doofinder.com` | `eu1-recommendations.doofinder.com` | `eu1-category-merchandising.doofinder.com` |
| `us1` | `us1-search.doofinder.com` | `us1-api.doofinder.com` | `us1-recommendations.doofinder.com` | `us1-category-merchandising.doofinder.com` |
| `ap1` | `ap1-search.doofinder.com` | `ap1-api.doofinder.com` | `ap1-recommendations.doofinder.com` | `ap1-category-merchandising.doofinder.com` |
Your zone is visible in the Doofinder Admin Panel and is also encoded in your API key prefix.
# Error Reference
Source: https://docs.doofinder.com/introduction/errors
HTTP error codes and error response formats across all Doofinder APIs.
All Doofinder APIs use standard HTTP status codes. When a request fails, the response body contains a JSON object describing the error.
## Error Response Format
Most errors return a JSON body with an `error` field:
```json theme={null}
{
"error": "Not found",
"resource": "Widget",
"resource_id": "cc1e9563-14e4-46f6-bdf3-42bc57083c25"
}
```
Validation errors include a `details` object with field-level messages:
```json theme={null}
{
"error": "Bad request",
"details": {
"session_id": ["length must be less than or equal to 32"],
"current_url": ["is required"]
}
}
```
***
## HTTP Status Codes
### `400 Bad Request`
The request contains invalid or missing parameters.
**Common causes:**
* Missing a required query parameter or body field
* A string parameter exceeds its maximum length (e.g. `session_id` > 32 chars, `query` > 200 chars or > 10 words)
* An enum value is not one of the allowed options
**Search API example — query too long:**
```json theme={null}
{ "error": "Bad request", "details": { "query": ["is too long (maximum is 200 characters)"] } }
```
***
### `401 Unauthorized`
The request is missing an `Authorization` header, or the provided API key is invalid.
**Common causes:**
* No `Authorization` header sent
* API key has been revoked or does not exist
* Wrong key format (e.g. using a JWT token where a plain token is expected)
***
### `403 Forbidden`
Access was denied even though authentication succeeded.
**Recommendations API specific variants:**
```json theme={null}
{ "error": "Forbidden origin" }
```
The request `Origin`/`Referer` is not in the store's allowed domains list.
```json theme={null}
{ "error": "Forbidden ip" }
```
The client IP is on the store's blocklist.
***
### `404 Not Found`
The requested resource does not exist.
**Management API example:**
```json theme={null}
{
"error": "Not found",
"resource": "SearchEngine",
"resource_id": "d8fdeab7fce96a19d3fc7b0ca7a1e98b"
}
```
***
### `413 Payload Too Large`
The request body exceeds **8 MB**. This limit applies to all POST/PUT/PATCH requests.
**Resolution:** Split large payloads into smaller batches. For bulk item operations, use batches of up to 100 items per request.
***
### `422 Unprocessable Entity`
The request is well-formed but cannot be processed due to a semantic error.
**Common cause:** Bulk item operations with more than **100 items** per request.
```json theme={null}
{ "error": "Unprocessable entity", "details": { "items": ["must have at most 100 items"] } }
```
***
### `429 Too Many Requests`
You have exceeded the rate limit of **20 requests per second**.
```json theme={null}
{ "error": "Too many requests" }
```
There is no penalty — wait one second before retrying. The limit resets automatically.
**Best practice for bulk operations:** Use the `_bulk` endpoints instead of sending individual item requests in rapid succession.
***
## Rate Limits Summary
| Limit | Value |
| -------------------------- | ------------------------- |
| Requests per second | 20 |
| Max request body size | 8 MB |
| Max items per bulk request | 100 |
| Max `query` length | 200 characters / 10 words |
| Max `session_id` length | 32 characters |
| Max `user_id` length | 36 characters |
***
## Retrying Requests
| Status | Retry? | Strategy |
| --------------------------------- | ------ | ------------------------------- |
| `429` | Yes | Wait 1 second, then retry |
| `500`, `502`, `503` | Yes | Exponential backoff |
| `400`, `401`, `403`, `404`, `422` | No | Fix the request before retrying |
# Quick Start
Source: https://docs.doofinder.com/introduction/quickstart
Make your first Doofinder API call in under 5 minutes.
## Prerequisites
1. A [Doofinder account](https://admin.doofinder.com/auth/signup) with at least one search engine configured
2. An API key — generate one at **Admin Panel → Account → API Keys**
Your API key looks like this: `eu1-ab46030xza33960aac71a10248489b6c26172f07`
The prefix (`eu1`, `us1`, `ap1`) is your **search zone** — you'll need it to construct the correct API hostname.
***
## Step 1 — Find your Search Engine ID (hashid)
Every Doofinder search engine has a unique `hashid`. You can find it in the Admin Panel under **Configuration → Search Engines** — hover over any engine to copy its hashid.
It looks like: `d8fdeab7fce96a19d3fc7b0ca7a1e98b`
***
## Step 2 — Run a search query
```bash cURL theme={null}
curl "https://eu1-search.doofinder.com/6/d8fdeab7fce96a19d3fc7b0ca7a1e98b/_search?query=shoes&rpp=5" \
-H "Authorization: Token eu1-ab46030xza33960aac71a10248489b6c26172f07"
```
```python Python theme={null}
import requests
ZONE = "eu1"
HASHID = "d8fdeab7fce96a19d3fc7b0ca7a1e98b"
API_KEY = "eu1-ab46030xza33960aac71a10248489b6c26172f07"
response = requests.get(
f"https://{ZONE}-search.doofinder.com/6/{HASHID}/_search",
params={"query": "shoes", "rpp": 5},
headers={"Authorization": f"Token {API_KEY}"}
)
data = response.json()
print(f"Found {data['total']} results")
for item in data["results"]:
print(f" - {item['title']}")
```
```javascript JavaScript theme={null}
const ZONE = "eu1";
const HASHID = "d8fdeab7fce96a19d3fc7b0ca7a1e98b";
const API_KEY = "eu1-ab46030xza33960aac71a10248489b6c26172f07";
const response = await fetch(
`https://${ZONE}-search.doofinder.com/6/${HASHID}/_search?query=shoes&rpp=5`,
{ headers: { Authorization: `Token ${API_KEY}` } }
);
const data = await response.json();
console.log(`Found ${data.total} results`);
data.results.forEach(item => console.log(` - ${item.title}`));
```
**Example response:**
```json theme={null}
{
"count": 142,
"total": 142,
"results": [
{
"id": "SKU-001",
"dfid": "d8fdeab7fce96a19d3fc7b0ca7a1e98b@product@abc123",
"title": "Running Shoes Pro",
"description": "Lightweight performance running shoes",
"url": "https://shop.example.com/products/running-shoes-pro",
"image_url": "https://shop.example.com/images/running-shoes-pro.jpg"
}
],
"query_name": "match_and"
}
```
***
## Step 3 — Log a click event
When a user clicks a result, log it so Doofinder can improve your rankings and stats:
```bash theme={null}
curl -X PUT "https://eu1-search.doofinder.com/6/d8fdeab7fce96a19d3fc7b0ca7a1e98b/stats/click" \
-H "Authorization: Token eu1-ab46030xza33960aac71a10248489b6c26172f07" \
-H "Content-Type: application/json" \
-d '{
"session_id": "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4",
"dfid": "d8fdeab7fce96a19d3fc7b0ca7a1e98b@product@abc123",
"query": "shoes",
"position": 1
}'
```
***
## Next Steps
Explore filters, facets, sorting, image search, and more.
Learn about API tokens, JWT, and zone-specific keys.
Push items and manage indices programmatically.
Handle errors gracefully in your integration.
# Management API
Source: https://docs.doofinder.com/management-api/overview
Manage Doofinder search engines, indices, and items programmatically.
The Management API lets you automate everything you can do in the Doofinder Admin Panel — creating search engines, managing the data structure (indices), and pushing, updating, or deleting items.
**Version:** v2
## Base URL
```
https://{search_zone}-api.doofinder.com
```
Example: `https://eu1-api.doofinder.com`
## Authentication
Supports both **API Token** and **JWT Bearer** token authentication:
```http theme={null}
Authorization: Token ab46030xza33960aac71a10248489b6c26172f07
```
```http theme={null}
Authorization: Bearer
```
See the [Authentication guide](/introduction/authentication) for JWT signing details.
***
## Endpoints Overview
CRUD operations on search engine configurations.
Manage the data types (indices) within a search engine.
Push, update, delete, and query individual items.
Full index replacement via temporary indices for zero-downtime updates.
***
## Search Engines
A **search engine** is the top-level container for your searchable data. It holds one or more indices and is identified by its `hashid`.
| Method | Path | Description |
| -------- | ------------------------------------------ | ----------------------------- |
| `GET` | `/api/v2/search_engines` | List all search engines |
| `POST` | `/api/v2/search_engines` | Create a new search engine |
| `GET` | `/api/v2/search_engines/{hashid}` | Get a specific search engine |
| `PATCH` | `/api/v2/search_engines/{hashid}` | Update search engine settings |
| `DELETE` | `/api/v2/search_engines/{hashid}` | Delete a search engine |
| `POST` | `/api/v2/search_engines/{hashid}/_process` | Trigger reprocessing |
| `GET` | `/api/v2/search_engines/{hashid}/_process` | Get reprocessing task status |
***
## Indices
An **index** is a named collection of items within a search engine. Most stores have a `product` index; you can also have `page`, `category`, or any custom index name.
| Method | Path | Description |
| -------- | ------------------------------------------------ | -------------------------- |
| `GET` | `/api/v2/search_engines/{hashid}/indices` | List indices |
| `POST` | `/api/v2/search_engines/{hashid}/indices` | Create an index |
| `GET` | `/api/v2/search_engines/{hashid}/indices/{name}` | Get index details |
| `PATCH` | `/api/v2/search_engines/{hashid}/indices/{name}` | Update index configuration |
| `DELETE` | `/api/v2/search_engines/{hashid}/indices/{name}` | Delete an index |
***
## Items
**Items** are the individual records in an index (products, pages, etc.). Use these endpoints for real-time, incremental updates.
| Method | Path | Description |
| -------- | ---------------------------------------------------------------- | ------------------------ |
| `GET` | `/api/v2/search_engines/{hashid}/indices/{name}/items/` | List/scroll items |
| `POST` | `/api/v2/search_engines/{hashid}/indices/{name}/items/` | Create a single item |
| `GET` | `/api/v2/search_engines/{hashid}/indices/{name}/items/{item_id}` | Get an item |
| `PATCH` | `/api/v2/search_engines/{hashid}/indices/{name}/items/{item_id}` | Update an item |
| `DELETE` | `/api/v2/search_engines/{hashid}/indices/{name}/items/{item_id}` | Delete an item |
| `GET` | `/api/v2/search_engines/{hashid}/indices/{name}/items/_count` | Count items |
| `POST` | `/api/v2/search_engines/{hashid}/indices/{name}/items/_mget` | Get multiple items by ID |
| `POST` | `/api/v2/search_engines/{hashid}/indices/{name}/items/_bulk` | Create items in bulk |
| `PATCH` | `/api/v2/search_engines/{hashid}/indices/{name}/items/_bulk` | Update items in bulk |
| `DELETE` | `/api/v2/search_engines/{hashid}/indices/{name}/items/_bulk` | Delete items in bulk |
### Bulk operations
Bulk endpoints accept up to **100 items per request**. For large catalogues, split into batches:
```json theme={null}
[
{ "id": "SKU-001", "title": "Running Shoes", "price": 89.99 },
{ "id": "SKU-002", "title": "Trail Runners", "price": 119.99 }
]
```
Requests with more than 100 items will be rejected with `422 Unprocessable Entity`. Always batch your payloads.
***
## Bulk Index Operations
For **full catalogue replacement** (e.g. nightly sync), use the temporary index workflow. This pattern allows a complete index swap with zero search downtime:
`POST /api/v2/search_engines/{hashid}/indices/{name}/temp/`
Creates a writable temporary index alongside the live one.
Use the temp item endpoints (`/temp/items/`, `/temp/items/_bulk`) to write your full catalogue.
These writes don't affect the live search index.
`POST /api/v2/search_engines/{hashid}/indices/{name}/_replace_by_temp/`
Atomically swaps the live index with the temporary one. Users continue searching against the old index until the swap completes.
Alternatively, use the **reindex** workflow for more control:
| Method | Path | Description |
| -------- | --------------------------------- | ---------------------------------------- |
| `POST` | `.../{name}/temp/` | Create temporary index |
| `DELETE` | `.../{name}/temp/` | Delete temporary index |
| `POST` | `.../{name}/temp/items/` | Add item to temp index |
| `GET` | `.../{name}/temp/items/{item_id}` | Get item from temp index |
| `PATCH` | `.../{name}/temp/items/{item_id}` | Update item in temp index |
| `DELETE` | `.../{name}/temp/items/{item_id}` | Delete item from temp index |
| `POST` | `.../{name}/temp/items/_bulk` | Create items in bulk in temp index |
| `PATCH` | `.../{name}/temp/items/_bulk` | Update items in bulk in temp index |
| `DELETE` | `.../{name}/temp/items/_bulk` | Delete items in bulk in temp index |
| `POST` | `.../{name}/temp/items/_mget` | Get multiple items by ID from temp index |
| `POST` | `.../{name}/_reindex_to_temp/` | Start reindex from live to temp |
| `GET` | `.../{name}/_reindex_to_temp/` | Get reindex task status |
| `POST` | `.../{name}/_replace_by_temp/` | Swap temp index into production |
***
## API Limits
| Limit | Value |
| -------------------------- | ------------------ |
| Rate limit | 20 requests/second |
| Max request body size | 8 MB |
| Max items per bulk request | 100 |
***
## Item Structure
Items are schema-flexible — you can include any fields your search engine is configured to index. Some fields are commonly expected:
| Field | Type | Description |
| ---------------- | ------ | --------------------------------------------------- |
| `id` | string | **Required.** Your item's unique identifier. |
| `title` | string | Item title (highly recommended for search quality). |
| `description` | string | Item description. |
| `url` | string | URL to the item page. |
| `image_url` | string | URL to the item image. |
| `price` | number | Item price. |
| `df_grouping_id` | string | Group variants under a single result. |
The fields indexed by your search engine are configured in the Admin Panel under **Configuration → Search Engines → \[engine]**. Only configured fields are searchable and facetable.
# Recommendations API
Source: https://docs.doofinder.com/recommendations-api/overview
Deliver personalized product recommendations using Doofinder's recommendation engine.
The Recommendations API powers recommendation widgets on your ecommerce site — showing users products they are likely to be interested in based on browsing history, cart contents, current page context, and user identity.
**Version:** v1
## Base URL
```
https://{search_zone}-recommendations.doofinder.com
```
Supported zones: `eu1`, `us1`, `ap1`
## Authentication
The Recommendations API does **not** use an `Authorization` header. Instead, the **widget ID** (a UUID configured in the Admin Panel) acts as the access credential and is passed in the URL path.
***
## How It Works
Go to **Recommendations** and click **Add Carousel**. Each carousel has a `widget_id` (UUID) that you use in the API.
POST to `/api/widget/{widget_id}` with context about the current page and user.
The response contains a `results` array of product recommendations and currency formatting details.
***
## Endpoint
```
POST https://{zone}-recommendations.doofinder.com/api/widget/{widget_id}
```
### Request body
```json theme={null}
{
"current_url": "https://shop.example.com/products/wireless-headphones",
"session_id": "b2b89619844f4eb0b5fa19f28a19d679",
"user_id": "8c80694b-354c-4533-acd1-e4b8e7d74b7b",
"hashid": "de8f052ea612f95b6950d4013dd6ef38",
"language": "en",
"price_name": "EUR",
"cart_items": [
{ "dfid": "de8f052ea612f95b6950d4013dd6ef38@product@e7b7a6c35b2d4afc94991bfc8100227a" }
],
"category_context": []
}
```
### Response
```json theme={null}
{
"title": "You might also like",
"currency": {
"code": "EUR",
"label": "Euro",
"format": "%v %s",
"symbol": "€",
"precision": 2,
"decimal": ",",
"thousand": "."
},
"fallback_action": "disabled",
"results": [
{
"id": "SKU-099",
"title": "Wireless Earbuds Pro",
"price": 79.99,
"url": "https://shop.example.com/products/wireless-earbuds-pro"
}
]
}
```
***
## Request Parameters
| Parameter | Required | Description |
| -------------------- | -------- | ----------------------------------------------------------------------------------------- |
| `current_url` | **Yes** | The full URL of the page where the widget is rendered. Used to determine product context. |
| `session_id` | No | 32-char session identifier. Required for **Browsing history** recommendation type. |
| `user_id` | No | Persistent user UUID. Enables cross-session personalization. |
| `hashid` | No | Search engine hash ID. Required when the widget is not tied to a specific search engine. |
| `language` | No | Language code (e.g. `en`, `es`). Filters results to the specified language. |
| `price_name` | No | Currency code (e.g. `EUR`, `USD`). Formats prices in the response. |
| `cart_items[]` | No | Array of `{ dfid }` objects representing items currently in the user's cart. |
| `category_context[]` | No | Category path context for category-aware recommendations. |
***
## Recommendation Types
The widget type configured in the Admin Panel determines what signals drive the recommendations:
| Type | Required fields | Description |
| ------------------------------ | ----------------------------- | -------------------------------------------------- |
| **Similar products** | `current_url` | Products similar to those on the current page |
| **Browsing history** | `current_url`, `session_id` | Products based on this session's browsing behavior |
| **Frequently bought together** | `current_url`, `cart_items[]` | Products often purchased with cart items |
| **Personalized** | `current_url`, `user_id` | Products personalized to the user's history |
| **Trending** | `current_url` | Currently popular products |
If the required signals are not provided for a recommendation type, the API falls back to a default strategy (if fallback is enabled for the widget). If no fallback is configured, an empty `results` array is returned.
***
## CORS
If your ecommerce site uses CORS, ensure the domain making the request is in your store's **Allowed Domains** list in the Admin Panel. Requests from unlisted domains return `403 Forbidden Origin`.
***
## Error Responses
| Status | Error | Description |
| ------ | ------------------- | ------------------------------------------------------------------------ |
| `400` | `Bad request` | Invalid or missing parameters. `details` field lists field-level errors. |
| `403` | `Forbidden origin` | Request origin not in allowed domains |
| `403` | `Forbidden ip` | Client IP is blocklisted |
| `404` | `Not found` | Widget ID does not exist |
| `429` | `Too many requests` | Rate limit exceeded |
```json theme={null}
{
"error": "Bad request",
"details": {
"current_url": ["is required"],
"session_id": ["length must be less than or equal to 32"]
}
}
```
# Search API
Source: https://docs.doofinder.com/search-api/overview
Query your Doofinder search engine, get suggestions, run image search, and track user interactions.
The Search API lets you integrate Doofinder's search capabilities directly into your application. It handles full-text search, autocomplete, image-based search, visually similar products, and session-level event tracking.
**Current version:** v6 (recommended)
Search API v5 is deprecated. If you are still on v5, migrate to v6 — paths changed from `/5/search` to `/6/{hashid}/_search` and the API now includes POST support, image search, and visually similar endpoints.
## Base URL
```text theme={null}
https://{search_zone}-search.doofinder.com
```
Replace `{search_zone}` with your zone (`eu1`, `us1`, `ap1`).
## Authentication
The Search API uses the standard Doofinder API key. The zone prefix is optional:
```http theme={null}
Authorization: Token eu1-ab46030xza33960aac71a10248489b6c26172f07
```
Generate keys in the [Admin Panel](https://admin.doofinder.com/admin/account/api).
***
## Endpoints
`GET/POST /6/{hashid}/_search` — Full-text search with filters, facets, sorting, and grouping.
`GET /6/{hashid}/_suggest` — Autocomplete terms as the user types.
`POST /6/{hashid}/_image_search` — Search by image (base64-encoded).
`GET /6/{hashid}/_visually_similar` — Find visually similar products by `dfid`.
### Session & Event Tracking
Sending session events is required for accurate stats and improved ranking via behavioral signals.
`PUT /6/{hashid}/stats/init` — Start a user session before the first search.
`PUT /6/{hashid}/stats/click` — Log when a user clicks a search result.
`PUT /6/{hashid}/stats/cart/{session_id}` — Log items added to cart.
`PUT /6/{hashid}/stats/redirect` — Log when a user follows a redirect rule.
***
## Key Concepts
### hashid
Every Doofinder search engine has a unique identifier called `hashid` (32-character hex string). All Search API paths include it:
```text theme={null}
GET /6/d8fdeab7fce96a19d3fc7b0ca7a1e98b/_search
```
Find your `hashid` in the Admin Panel under **Configuration → Search Engines** — hover over any engine to copy its hashid.
### Indices
A search engine can have multiple indices (e.g. `product`, `page`, `category`). By default, all indices are searched. Use the `indices[]` parameter to restrict to one or more:
```text theme={null}
?indices[]=product&indices[]=page
```
### session\_id and user\_id
Track user sessions and identities to enable personalization and accurate analytics:
| Field | Max length | Description |
| ------------ | ---------- | ------------------------------------------------------------------------------ |
| `session_id` | 32 chars | Unique per browsing session. Generate a new one per visit. |
| `user_id` | 36 chars | Persistent user identifier (e.g. UUID). Enables cross-session personalization. |
***
## Filters and Facets
### Filter parameters
Narrow results by field values. Term filters accept arrays; range filters use `gte`, `lte`, `gt`, `lt`:
```text theme={null}
filter[color][]=blue&filter[color][]=red&filter[price][gte]=10&filter[price][lte]=100
```
URL-encode brackets: `[` → `%5B`, `]` → `%5D`.
For complex filters, use the `POST` variant and send a JSON body:
```json theme={null}
{
"query": "shoes",
"filter": {
"color": ["blue", "red"],
"price": { "gte": 10, "lte": 100 }
}
}
```
### Facet aggregations
Request aggregations to power filter UI:
```text theme={null}
facets[0][field]=brand&facets[0][size]=10&facets[1][field]=price&facets[1][type]=range
```
The response includes term counts and range min/max for each requested facet.
***
## Multiprice Format
Doofinder supports multiple prices per product (e.g. for different currencies or customer groups). Index your items with price fields named using the convention `price_{name}` (e.g. `price_eur`, `price_usd`, `price_member`).
To filter by a specific price field:
```text theme={null}
filter[price_eur][gte]=10&filter[price_eur][lte]=100
```
To sort by a specific price:
```text theme={null}
sort[0][price_eur]=asc
```
The `price_name` parameter in the Recommendations API body accepts the currency code (e.g. `"EUR"`) to format prices in the response.
***
## Grouping and Variants
When your catalogue has product variants (e.g. different sizes/colors of the same product), use grouping to collapse them into a single result:
| Parameter | Default | Description |
| ----------------- | ----------------- | ----------------------------------------------------------- |
| `grouping` | from Admin config | Collapse variants sharing the same `df_grouping_id` |
| `with_variants[]` | — | When grouping is on, include these fields from each variant |
```json theme={null}
{
"query": "t-shirt",
"grouping": true,
"with_variants": ["size", "color", "price"]
}
```
***
## Query Types
Doofinder automatically picks the best query strategy, but you can override it with `query_name`:
| Value | Behavior |
| ----------- | ----------------------------------------------- |
| `match_and` | All terms must appear in results |
| `match_or` | Any term can appear (higher score if all match) |
| `fuzzy` | Applies fuzzy matching for typo tolerance |
The response always includes `query_name` so you can see which strategy was used.
# Stats API
Source: https://docs.doofinder.com/stats-api/overview
Retrieve analytics and usage data for your Doofinder search engines.
The Stats API provides access to aggregated analytics data for your search engines — search volumes, click-through rates, conversion metrics, facet usage, and more. All data is read-only.
**Version:** v2
## Base URL
```
https://{search_zone}-api.doofinder.com
```
Example: `https://eu1-api.doofinder.com`
## Authentication
```http theme={null}
Authorization: Token ab46030xza33960aac71a10248489b6c26172f07
```
JWT authentication is also supported. See the [Authentication guide](/introduction/authentication).
***
## Common Query Parameters
Most endpoints accept these parameters to define the reporting window:
| Parameter | Type | Description |
| --------- | ------ | ------------------------------------------------------ |
| `hashid` | string | **Required.** Your search engine's identifier. |
| `from` | string | Start date in `YYYY-MM-DD` format. |
| `to` | string | End date in `YYYY-MM-DD` format. |
| `tz` | string | Timezone for date aggregations (e.g. `Europe/Madrid`). |
***
## Endpoint Groups
Session counts, user activity, geographic breakdowns, and per-engine usage.
Search volume, top queries, popular terms, location data.
Click-through rates, clicked items, position analysis, redirects.
Checkout and sales data attributed to search sessions.
Banners, facets, custom results, recommendations, quizzes.
***
## Usage & Sessions
Track how users are engaging with your search engine over time.
| Method | Path | Description |
| ------ | ----------------------------------- | ------------------------------------------- |
| `GET` | `/api/v2/stats/inits` | Total session counts over time |
| `GET` | `/api/v2/stats/inits/locations` | Sessions broken down by geographic location |
| `GET` | `/api/v2/stats/inits/users` | Sessions with identified users |
| `GET` | `/api/v2/stats/usage` | Overall usage metrics |
| `GET` | `/api/v2/stats/search_engine_users` | Per-engine usage by user |
***
## Searches
Understand what your users are searching for.
| Method | Path | Description |
| ------ | ---------------------------------- | ------------------------------------- |
| `GET` | `/api/v2/stats/searches` | Search volume over time |
| `GET` | `/api/v2/stats/searches/top` | Top search queries ranked by volume |
| `GET` | `/api/v2/stats/searches/popular` | Popular searches (trending) |
| `GET` | `/api/v2/stats/searches/locations` | Searches broken down by location |
| `GET` | `/api/v2/stats/results/top` | Most-returned results across searches |
***
## Clicks & Interactions
Measure how users interact with search results.
| Method | Path | Description |
| ------ | -------------------------------------- | ---------------------------------------- |
| `GET` | `/api/v2/stats/clicks` | Click volume over time |
| `GET` | `/api/v2/stats/clicks/users` | Clicks attributed to identified users |
| `GET` | `/api/v2/stats/clicked_items` | Items most frequently clicked |
| `GET` | `/api/v2/stats/clicked_items/searches` | Searches that led to clicks on each item |
| `GET` | `/api/v2/stats/clicked_items/position` | Average click position per item |
| `GET` | `/api/v2/stats/redirects` | Redirect rule trigger counts |
***
## Conversions & Sales
Attribute revenue and conversions to search-driven sessions.
| Method | Path | Description |
| ------ | ------------------------- | ---------------------------------------------- |
| `GET` | `/api/v2/stats/checkouts` | Checkout events initiated from search sessions |
| `GET` | `/api/v2/stats/sales` | Sales data |
| `POST` | `/api/v2/stats/sales` | Confirm a sale event |
| `GET` | `/api/v2/stats/top-sales` | Top-selling items attributed to search |
| `POST` | `/api/v2/stats/carts` | Process checkout cart data |
***
## Features
Track usage of specific Doofinder features.
| Method | Path | Description |
| ------ | ------------------------------- | --------------------------------------- |
| `GET` | `/api/v2/stats/banners` | Banner impression and click stats |
| `GET` | `/api/v2/stats/facets` | Facet usage — which filters users apply |
| `GET` | `/api/v2/stats/facets_by_day` | Daily facet usage breakdown |
| `GET` | `/api/v2/stats/facets/top` | Top facet values by usage |
| `GET` | `/api/v2/stats/custom-results` | Custom result rule usage |
| `GET` | `/api/v2/stats/recommendations` | Recommendation widget stats |
| `GET` | `/api/v2/stats/quizzes` | Quiz feature stats |
| `GET` | `/api/v2/stats/sector/{name}` | Industry-specific benchmark data |
| `POST` | `/api/v2/stats/visit` | Log a page visit event |
***
## Key Metrics Explained
### Click-Through Rate (CTR)
The ratio of search sessions that result in at least one click. A low CTR on a query suggests results are not relevant.
### Zero Results Rate
The percentage of searches that return no results. Monitor `GET /api/v2/stats/searches` for queries with `total_results: 0`.
### Session Attribution
Doofinder attributes a sale or checkout to a search session if the user clicked a search result and subsequently completed a purchase within the same session window.