Search terms API
Manage search terms and their redirect URLs. These endpoints mirror Magento's own Search Terms screen at Marketing -> SEO & Search -> Search Terms — same fields, same validation, same effects. All endpoints require authentication and the Magento_Search::search ACL resource.
Search terms are Magento's own entity, and the platform writes rows into it from real shopper queries. The same rows feed the popular-searches surface on your storefront, so a careless write changes what shoppers are shown there.
Search term object
| Field | Description | Type | Required |
|---|---|---|---|
query_id | Unique term identifier | Int | Read-only |
query_text | The phrase a shopper searches for | String | Yes |
store_id | Store view the term belongs to | Int | No, but see below |
redirect | Full URL the shopper is sent to instead of the results page; empty means no redirect | String | No |
display_in_terms | Whether the term appears in the storefront search-terms list: 1 or 0 | Int | No |
is_active | Whether the term is active: 1 or 0 | Int | No |
num_results | Number of results the term last produced | Int | Read-only |
popularity | How often shoppers searched it | Int | Read-only |
is_processed | Platform's own processing flag | Int | Read-only |
updated_at | Last update timestamp | String | Read-only |
The read-only fields are maintained by Magento from real shopper traffic. They carry no setter, so a write that includes one is refused rather than silently ignored.
store_idA search term belongs to exactly one store view, and shoppers only ever match terms in the store view they are browsing. Omitting store_id does not fail — the term is stored against store 0, which no storefront searches — so the write returns 200, the row is there when you read it back, and nothing you do on the storefront will ever trigger it.
Get search term
GET /rest/V1/mst-search/search-terms/:queryId
Response:
{
"query_id": 15,
"query_text": "zorblat-doc",
"store_id": 1,
"redirect": "https://example.com/gear/bags.html",
"display_in_terms": 1,
"is_active": 1,
"num_results": 0,
"popularity": 0,
"is_processed": 0,
"updated_at": "2026-09-15 08:52:00"
}
Errors: 404 — no term with that ID.
List search terms
GET /rest/V1/mst-search/search-terms?searchCriteria
Supports filtering and pagination on any field of the object — store_id, query_text with like, popularity with gteq, and so on.
Example — the most-searched terms on store view 1:
GET /rest/V1/mst-search/search-terms
?searchCriteria[filter_groups][0][filters][0][field]=store_id
&searchCriteria[filter_groups][0][filters][0][value]=1
&searchCriteria[sort_orders][0][field]=popularity
&searchCriteria[sort_orders][0][direction]=DESC
&searchCriteria[pageSize]=20
Create search term
POST /rest/V1/mst-search/search-terms
Request body:
{
"searchTerm": {
"query_text": "zorblat-doc",
"store_id": 1,
"redirect": "https://example.com/gear/bags.html",
"display_in_terms": 1,
"is_active": 1
}
}
Response: the created term with query_id assigned. Fields you omit come back with their defaults, so the response always matches what a following GET returns.
Errors:
400—You already have an identical search term query.The term already exists on that store view; a term is unique per store view, exactly as in the admin form.400—Redirect URL must be a full address starting with http://, https:// or ftp://.See Redirect validation.
Update search term
PUT /rest/V1/mst-search/search-terms/:queryId
This is a partial update. Only the fields present in the body are applied, so omitting redirect, display_in_terms, or is_active leaves them exactly as they were:
{
"searchTerm": {
"is_active": 0
}
}
To clear a redirect, send it explicitly as an empty string:
{
"searchTerm": {
"redirect": ""
}
}
Response: the updated term.
Errors: 404 — no term with that ID. 400 — a duplicate query_text on the same store view, an invalid redirect, or a write to a read-only field.
Delete search term
DELETE /rest/V1/mst-search/search-terms/:queryId
Response:
true
Errors: 404 — no term with that ID.
Magento recreates a search term the next time a shopper searches that text, so a deleted term can reappear on its own, with its counters starting again from zero. Deleting is the right way to clear a stale redirect or tidy the list, but it is not a way to stop a phrase from ever being recorded again.
Redirect validation
A redirect target must be a full address beginning with http://, https://, or ftp:// — the same rule the admin form applies. A relative path such as /gear/bags.html, a script-scheme URL such as javascript:alert(1), or anything that is not a URL is refused with 400 and nothing is stored:
{
"message": "Redirect URL must be a full address starting with http://, https:// or ftp://."
}
A redirect set over REST takes effect immediately — the next shopper who searches the term is sent to the target, with no cache flush and no reindex.
Auditing redirects
Filtering the list to terms that carry a redirect gives you every redirect currently in force on the store. This is the supported way to find redirects whose target was since deleted or moved and now sends shoppers to a 404 — run the list, then check each target.
GET /rest/V1/mst-search/search-terms
?searchCriteria[filter_groups][0][filters][0][field]=redirect
&searchCriteria[filter_groups][0][filters][0][condition_type]=neq
&searchCriteria[filter_groups][0][filters][0][value]=
Response:
{
"items": [
{
"query_id": 15,
"query_text": "zorblat-doc",
"store_id": 1,
"redirect": "https://example.com/gear/bags.html",
"display_in_terms": 1,
"is_active": 1,
"num_results": 0,
"popularity": 0,
"is_processed": 0,
"updated_at": "2026-09-15 08:52:10"
}
],
"search_criteria": {
"filter_groups": [
{ "filters": [ { "field": "redirect", "value": "", "condition_type": "neq" } ] }
]
},
"total_count": 1
}
A broken target is then fixed with a PUT carrying only the new redirect, or cleared with an empty one.