Hydra is now in beta|Get started free|Follow our journey on X.com

Search API
On this page

Search

Hydra provides a powerful search engine with typo correction, synonym expansion, faceted filtering, and merchandising controls. Search queries are logged for analytics, and results can be influenced through synonym groups and merchandising rules (pin, boost, bury, hide).

Full-text search indexes the following fields with weighted relevance:

Weight Fields Description
A Product title Highest relevance, stemmed
B Product description Secondary relevance, stemmed
C Tags, product type Consumer search terms, exact match
D Variant SKU, barcode Staff/B2B lookups, exact match

All fields are indexed automatically — no configuration required.

Search relevance

For projects using the Skirre search engine, search ranking is a blend of three signals:

  1. Keyword relevance (BM25) — how well the query matches indexed text fields, weighted by the table above
  2. Semantic similarity (optional) — meaning-based matching via vector embeddings, for queries like “comfortable running shoes” matching “ergonomic jogging sneakers”
  3. Popularity scoring (optional) — behavioral signals (purchases, clicks, views) automatically boost popular products. Skirre aggregates these from shopper events every 6 hours. No configuration beyond enabling scoring in the search engine settings

Commerce-based scoring (sales velocity, revenue, inventory health) is computed nightly by Hydra and applied during index bootstraps. When Skirre’s behavioral scoring is also enabled, both signals combine for the most accurate ranking.

Base URL: https://api.hydrajs.dev

Endpoints

Method Path Auth Description
GET /v1/search Publishable Search products and collections
GET /v1/search/suggest Publishable Get typeahead suggestions
POST /v1/search/synonyms Secret Create a synonym group
GET /v1/search/synonyms Secret List synonym groups
PATCH /v1/search/synonyms/{id} Secret Update a synonym group
DELETE /v1/search/synonyms/{id} Secret Delete a synonym group
POST /v1/search/merchandising Secret Create a merchandising rule
GET /v1/search/merchandising Secret List merchandising rules
GET /v1/search/merchandising/{id} Secret Get a merchandising rule
PATCH /v1/search/merchandising/{id} Secret Update a merchandising rule
DELETE /v1/search/merchandising/{id} Secret Delete a merchandising rule
POST /v1/search/bootstrap Secret Rebuild the search index
GET /v1/search/analytics/top-queries Secret Top search queries
GET /v1/search/analytics/zero-results Secret Zero-result queries

Search products and collections

GET /v1/search

Returns search results across one or more resource types. Supports typo correction, synonym expansion, faceted filtering, and multi-currency price conversion.

Query parameters

Parameter Type Default Description
q string - Search term (1-200 chars, required)
types string products Comma-separated: products, collections
limit integer 20 Results per type (1-50)
offset integer 0 Result offset for pagination (0-1000)
product_type string - Filter products by type
collection_id string - Filter products by collection
tag string - Filter products by tag
in_stock string - true for in-stock only, false for out-of-stock only
price_min integer - Minimum price in cents
price_max integer - Maximum price in cents
facets string true Include facet counts in response (true or false)
currency string - 3-letter ISO currency code for price conversion

ℹSearch syntax

Hydra supports Google-style search operators. Use quotes for exact phrases ("red sneakers"), a minus sign to exclude terms (sneakers -nike), and OR for alternatives (sneakers OR trainers). Typo correction is applied automatically.

Request

curl "https://api.hydrajs.dev/v1/search?q=sneakers&types=products&limit=10&in_stock=true" \
  -H "Authorization: Bearer pk_YOUR_KEY"

Response 200

{
	"data": {
		"products": {
			"data": [
				{
					"id": "prod_abc123",
					"title": "Classic Sneakers",
					"handle": "classic-sneakers",
					"status": "active",
					"product_type": "Footwear",
					"tags": ["sneakers", "footwear"],
					"skus": ["SNKR-BLK-10", "SNKR-WHT-10"],
					"image": "https://cdn.hydrajs.dev/stores/store_xxx/img_abc.webp",
					"price": 8999,
					"sale_price": 11999,
					"score": 1.85
				}
			],
			"total": 24
		},
		"collections": {
			"data": [],
			"total": 0
		}
	}
}

Get search suggestions

GET /v1/search/suggest

Returns typeahead suggestions based on a query prefix. The suggestion source depends on the project’s search engine:

  • Skirre — query-based suggestions derived from search analytics (popular queries, click-through rates, conversions) and catalog data (product titles, types, brands, tags). Suggestions are scored and maintained automatically. An empty q returns the most popular suggestions.
  • Default (Postgres) — entity-based suggestions from product titles, collection names, product types, tags, and variant titles using trigram similarity ranking.

Query parameters

Parameter Type Default Description
q string "" Partial search term (0-100 chars). Empty returns popular suggestions
limit integer 5 Max suggestions (1-10)

Request

curl "https://api.hydrajs.dev/v1/search/suggest?q=snea&limit=5" \
  -H "Authorization: Bearer pk_YOUR_KEY"

Response 200 (Skirre)

{
	"data": [
		{ "text": "sneakers", "type": "product" },
		{ "text": "sneaker collection", "type": "product" },
		{ "text": "snow boots", "type": "product" }
	]
}

Skirre returns query-level suggestions — each entry is a search query string. Results are ranked by a blended score of search frequency, click-through rate, and conversion rate. Catalog-derived suggestions provide a baseline from day one (cold start), and analytics-derived suggestions take over as search traffic builds.

Response 200 (default)

{
	"data": [
		{ "text": "Classic Sneakers", "type": "product", "id": "prod_abc123", "handle": "classic-sneakers", "image": "https://cdn.hydrajs.dev/stores/store_xxx/img_abc.webp" },
		{ "text": "Footwear", "type": "product_type" },
		{ "text": "sneakers", "type": "tag" },
		{ "text": "Sneaker Collection", "type": "collection", "id": "col_def456", "handle": "sneaker-collection" },
		{ "text": "Size 10 / Black", "type": "variant" }
	]
}

The default engine returns entity-based suggestions. Each includes a type field: product, collection, product_type, tag, or variant. Products and collections include id, handle, and optionally image for building direct links.


Bootstrap search index

POST /v1/search/bootstrap

Reads all active products from the database and pushes them to the search index in batches. Use this after bulk imports, data migrations, or when search results appear stale.

⚠Requirements

This endpoint only works when the store’s search engine is set to skirre. Calling it on a store using the default Postgres search engine returns a 400 error.

No request body is required. The endpoint reads all active, non-deleted products and indexes them automatically. The index language is set based on the project’s locale setting — for example, a project with locale fr or fr-FR uses French tokenization with accent folding, while ja uses Japanese dictionary-based word segmentation.

Request

curl -X POST "https://api.hydrajs.dev/v1/search/bootstrap" \
  -H "Authorization: Bearer sk_YOUR_SECRET_KEY"

Response 200

{
	"indexed": 369
}

The indexed field indicates the total number of products pushed to the search index.


Create a synonym group

POST /v1/search/synonyms

Creates a synonym group. When a user searches for any term in the group, results for all terms are included.

Request body

Field Type Required Description
synonym_type string No equivalent (default) or oneway. Equivalent synonyms expand in all directions; one-way synonyms only expand the first term to the rest
terms string[] Yes Array of synonym terms (2-20 terms, each max 100 chars)

ℹSynonym types

With equivalent synonyms, searching for any term returns results for all terms. With one-way synonyms, only the first term triggers expansion - searching for later terms returns only those exact results.

Request

curl -X POST https://api.hydrajs.dev/v1/search/synonyms \
  -H "Authorization: Bearer sk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "synonym_type": "equivalent",
    "terms": ["sneakers", "trainers", "kicks"]
  }'

Response 201

{
	"data": {
		"id": "syn_abc123",
		"synonym_type": "equivalent",
		"terms": ["sneakers", "trainers", "kicks"],
		"is_active": true,
		"created_at": "2026-08-17T10:00:00Z",
		"updated_at": "2026-08-17T10:00:00Z"
	}
}

List synonym groups

GET /v1/search/synonyms

Returns all synonym groups for the project, ordered by creation date.

Request

curl https://api.hydrajs.dev/v1/search/synonyms \
  -H "Authorization: Bearer sk_YOUR_KEY"

Response 200

{
	"data": [
		{
			"id": "syn_abc123",
			"synonym_type": "equivalent",
			"terms": ["sneakers", "trainers", "kicks"],
			"is_active": true,
			"created_at": "2026-08-17T10:00:00Z",
			"updated_at": "2026-08-17T10:00:00Z"
		},
		{
			"id": "syn_def456",
			"synonym_type": "oneway",
			"terms": ["laptop", "notebook", "ultrabook"],
			"is_active": true,
			"created_at": "2026-08-16T08:00:00Z",
			"updated_at": "2026-08-16T08:00:00Z"
		}
	]
}

Update a synonym group

PATCH /v1/search/synonyms/{id}

Updates a synonym group. All fields are optional.

Request body

Field Type Description
synonym_type string equivalent or oneway
terms string[] Replacement terms (2-20)
is_active boolean Enable or disable the synonym

Request

curl -X PATCH https://api.hydrajs.dev/v1/search/synonyms/syn_abc123 \
  -H "Authorization: Bearer sk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "terms": ["sneakers", "trainers", "kicks", "tennis shoes"]
  }'

Response 200

{
	"data": {
		"id": "syn_abc123",
		"synonym_type": "equivalent",
		"terms": ["sneakers", "trainers", "kicks", "tennis shoes"],
		"is_active": true,
		"created_at": "2026-08-17T10:00:00Z",
		"updated_at": "2026-08-17T10:05:00Z"
	}
}

Delete a synonym group

DELETE /v1/search/synonyms/{id}

Permanently deletes a synonym group.

Request

curl -X DELETE https://api.hydrajs.dev/v1/search/synonyms/syn_abc123 \
  -H "Authorization: Bearer sk_YOUR_KEY"

Response 204

Empty body.


Create a merchandising rule

POST /v1/search/merchandising

Creates a rule that influences search results for matching queries. Rules can pin products to specific positions, boost or bury their relevance scores, or hide them entirely.

Request body

Field Type Required Description
name string Yes Human-readable name (max 200 chars)
match_query string Yes Query pattern to match (max 200 chars)
match_type string No contains (default), exact, or all (matches every query)
action string Yes pin, boost, bury, or hide
product_id string Yes Product ID to apply the action to
pin_position integer Conditional Required when action is pin. Zero-based position in results
score_multiplier number Conditional Required when action is boost or bury. Multiplier for relevance score (0.01-100)
priority integer No Rule priority (0-1000, default 0). Higher priority rules are evaluated first

⚠Action requirements

pin requires pin_position. boost and bury require score_multiplier. Two active pin rules cannot share the same (match_query, match_type, pin_position) combination.

Request

curl -X POST https://api.hydrajs.dev/v1/search/merchandising \
  -H "Authorization: Bearer sk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Promote summer sneakers",
    "match_query": "sneakers",
    "match_type": "contains",
    "action": "pin",
    "product_id": "prod_abc123",
    "pin_position": 0,
    "priority": 10
  }'

Response 201

{
	"data": {
		"id": "mr_abc123",
		"name": "Promote summer sneakers",
		"match_query": "sneakers",
		"match_type": "contains",
		"action": "pin",
		"product_id": "prod_abc123",
		"pin_position": 0,
		"score_multiplier": null,
		"priority": 10,
		"is_active": true,
		"created_at": "2026-08-17T10:00:00Z",
		"updated_at": "2026-08-17T10:00:00Z"
	}
}

List merchandising rules

GET /v1/search/merchandising

Returns all merchandising rules, ordered by priority (descending) then creation date.

Request

curl https://api.hydrajs.dev/v1/search/merchandising \
  -H "Authorization: Bearer sk_YOUR_KEY"

Response 200

{
	"data": [
		{
			"id": "mr_abc123",
			"name": "Promote summer sneakers",
			"match_query": "sneakers",
			"match_type": "contains",
			"action": "pin",
			"product_id": "prod_abc123",
			"pin_position": 0,
			"score_multiplier": null,
			"priority": 10,
			"is_active": true,
			"created_at": "2026-08-17T10:00:00Z",
			"updated_at": "2026-08-17T10:00:00Z"
		},
		{
			"id": "mr_def456",
			"name": "Boost premium brand",
			"match_query": "shoes",
			"match_type": "contains",
			"action": "boost",
			"product_id": "prod_xyz789",
			"pin_position": null,
			"score_multiplier": 2.5,
			"priority": 5,
			"is_active": true,
			"created_at": "2026-08-16T08:00:00Z",
			"updated_at": "2026-08-16T08:00:00Z"
		}
	]
}

Get a merchandising rule

GET /v1/search/merchandising/{id}

Returns a single merchandising rule by ID.

Request

curl https://api.hydrajs.dev/v1/search/merchandising/mr_abc123 \
  -H "Authorization: Bearer sk_YOUR_KEY"

Response 200

{
	"data": {
		"id": "mr_abc123",
		"name": "Promote summer sneakers",
		"match_query": "sneakers",
		"match_type": "contains",
		"action": "pin",
		"product_id": "prod_abc123",
		"pin_position": 0,
		"score_multiplier": null,
		"priority": 10,
		"is_active": true,
		"created_at": "2026-08-17T10:00:00Z",
		"updated_at": "2026-08-17T10:00:00Z"
	}
}

Update a merchandising rule

PATCH /v1/search/merchandising/{id}

Updates a merchandising rule. All fields are optional. Changing the action may require providing the corresponding parameter (pin_position for pin, score_multiplier for boost/bury).

Request body

Field Type Description
name string Human-readable name (max 200 chars)
match_query string Query pattern to match (max 200 chars)
match_type string contains, exact, or all
action string pin, boost, bury, or hide
product_id string Product ID to target
pin_position integer | null Position for pin action
score_multiplier number | null Multiplier for boost/bury actions
priority integer Rule priority (0-1000)
is_active boolean Enable or disable the rule

Request

curl -X PATCH https://api.hydrajs.dev/v1/search/merchandising/mr_abc123 \
  -H "Authorization: Bearer sk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "pin_position": 1,
    "priority": 20
  }'

Response 200

Returns the full updated merchandising rule object.


Delete a merchandising rule

DELETE /v1/search/merchandising/{id}

Permanently deletes a merchandising rule.

Request

curl -X DELETE https://api.hydrajs.dev/v1/search/merchandising/mr_abc123 \
  -H "Authorization: Bearer sk_YOUR_KEY"

Response 204

Empty body.


Top search queries

GET /v1/search/analytics/top-queries

Returns the most popular search queries over a time period, ranked by frequency.

Query parameters

Parameter Type Default Description
period string 7d Time period: 1d, 7d, 14d, 30d
limit integer 20 Max results (1-100)

Request

curl "https://api.hydrajs.dev/v1/search/analytics/top-queries?period=7d&limit=10" \
  -H "Authorization: Bearer sk_YOUR_KEY"

Response 200

{
	"data": [
		{ "query": "sneakers", "count": 342, "avg_results": 18 },
		{ "query": "t-shirt", "count": 256, "avg_results": 45 },
		{ "query": "jeans", "count": 198, "avg_results": 32 }
	]
}

Zero-result queries

GET /v1/search/analytics/zero-results

Returns search queries that returned no results over a time period. Use this to identify gaps in your catalog or opportunities to add synonyms.

Query parameters

Parameter Type Default Description
period string 7d Time period: 1d, 7d, 14d, 30d
limit integer 20 Max results (1-100)

Request

curl "https://api.hydrajs.dev/v1/search/analytics/zero-results?period=30d&limit=10" \
  -H "Authorization: Bearer sk_YOUR_KEY"

Response 200

{
	"data": [
		{ "query": "sandals", "count": 87 },
		{ "query": "waterproof jacket", "count": 42 },
		{ "query": "running shoes size 15", "count": 15 }
	]
}

ℹImproving zero-result queries

When you spot recurring zero-result queries, consider adding synonym groups to map those terms to existing products, or use the data to inform catalog expansion.


The synonym object

Field Type Description
id string Unique ID (prefix: syn_)
synonym_type string equivalent or oneway
terms string[] Array of synonym terms (lowercased)
is_active boolean Whether the synonym is active
created_at string ISO 8601 timestamp
updated_at string ISO 8601 timestamp

The merchandising rule object

Field Type Description
id string Unique ID (prefix: mr_)
name string Human-readable rule name
match_query string Query pattern to match (lowercased)
match_type string contains, exact, or all
action string pin, boost, bury, or hide
product_id string Target product ID
pin_position integer | null Zero-based position (pin action only)
score_multiplier number | null Relevance multiplier (boost/bury only)
priority integer Evaluation priority (higher = first)
is_active boolean Whether the rule is active
created_at string ISO 8601 timestamp
updated_at string ISO 8601 timestamp