Search Engine API
Beyond the automatic Feed Reindex schedule, SoloSearch exposes a small public API to trigger a reindex on demand and to push changes for a single product immediately — no waiting for the next scheduled run, and no need to regenerate your whole feed file for a one-product change.
All requests are made directly to api.solosearch.app (not the panel, not the widget host), and all of them operate on a single search engine, identified by its UUID.
Authentication
Every request needs an Authorization: Bearer {token} header, using the API token shown on your search engine's General → API Token section. If no token has been generated yet, click Generate — the plain token is only ever shown once, immediately after generating it, so copy it somewhere safe.
Authorization: Bearer your-api-token-here
A missing or invalid token returns:
{ "message": "Invalid or missing API token." }
with HTTP status 401.
Reindex a feed
POST /api/v1/search-engines/{uuid}/reindex
Triggers a full Feed Reindex immediately, instead of waiting for the feed's own schedule (Daily/Weekly). This is what our official platform modules (e.g. Magento) call automatically every time your feed file is regenerated, so the index stays in sync without any manual action. See How the system works for what a Feed Reindex actually does.
No request body needed.
curl -X POST "https://api.solosearch.app/api/v1/search-engines/{uuid}/reindex" \
-H "Authorization: Bearer your-api-token-here"
| Status | Meaning |
|---|---|
200 |
Reindex scheduled. |
401 |
Invalid or missing token. |
404 |
Search engine not found. |
422 |
The search engine has no fetchable feed configured (e.g. its feed is set to Upload). |
429 |
Too many reindex requests — limited to 5 per hour per search engine, since each one downloads and re-parses your whole feed file. |
Add or update a product
PUT /api/v1/search-engines/{uuid}/products/{id}
Creates or replaces a single product in the search index right now. There's no separate "add" vs "update" — sending an id that doesn't exist yet creates it, sending one that already exists replaces it entirely with the body you send.
{id} is the product's SoloSearch id (the same value shown as the id field in your feed) — it's taken from the URL, never from the request body.
The request body is a JSON object using the same field names your feed already uses — whatever is configured in Configuration → Feeds → [your feed] → Feed Fields, not SoloSearch's internal field names. In other words, send the same data you'd put in one row/item of your feed file, as JSON:
curl -X PUT "https://api.solosearch.app/api/v1/search-engines/{uuid}/products/1042" \
-H "Authorization: Bearer your-api-token-here" \
-H "Content-Type: application/json" \
-d '{
"title": "Running Shoes",
"link": "https://myshop.com/running-shoes",
"image": "https://myshop.com/images/shoes.jpg",
"price": "89.99",
"sale_price": "69.99",
"categories": "Footwear %% Running"
}'
Whichever fields are marked required in your Feed Fields configuration are required here too — the request is rejected if one is missing, the same way a product missing that field would be skipped during a full Feed Reindex.
| Status | Meaning |
|---|---|
200 |
Product indexed. |
401 |
Invalid or missing token. |
404 |
Search engine not found. |
422 |
No feed configured, the search engine hasn't been indexed yet, or a required field is missing (the response names the missing field). |
429 |
Too many requests — limited to 60 per minute. |
Batch add or update products
POST /api/v1/search-engines/{uuid}/products/batch
Same as Add or update a product, but for many products in a single request — one OpenSearch write instead of one HTTP call per product. Useful for bulk operations (e.g. a full catalogue price update) where calling the single-product endpoint hundreds or thousands of times would be slower and more likely to hit its rate limit.
The body is a JSON object with a products array. Unlike the single-product endpoint, each item carries its own id field — there's no per-product URL to take it from:
curl -X POST "https://api.solosearch.app/api/v1/search-engines/{uuid}/products/batch" \
-H "Authorization: Bearer your-api-token-here" \
-H "Content-Type: application/json" \
-d '{
"products": [
{ "id": "1042", "title": "Running Shoes", "link": "https://myshop.com/running-shoes", "image": "https://myshop.com/images/shoes.jpg", "price": "89.99" },
{ "id": "1043", "title": "Trail Shoes", "link": "https://myshop.com/trail-shoes", "image": "https://myshop.com/images/trail.jpg", "price": "99.99" }
]
}'
A batch is not all-or-nothing — every item gets its own result, so one invalid product doesn't block the rest:
{
"indexed": 1,
"failed": 1,
"results": [
{ "id": "1042", "success": true, "error": null },
{ "id": "1043", "success": false, "error": "Missing required field: title." }
]
}
Maximum 500 products per request — split larger batches into multiple calls.
| Status | Meaning |
|---|---|
200 |
Request processed — check results for the outcome of each product; a 200 does not mean every product succeeded. |
401 |
Invalid or missing token. |
404 |
Search engine not found. |
422 |
No feed configured, the search engine hasn't been indexed yet, the body isn't a products array, or the batch exceeds 500 products. |
429 |
Too many requests — limited to 20 per minute. |
Delete a product
DELETE /api/v1/search-engines/{uuid}/products/{id}
Removes a single product from the search index. No request body needed.
curl -X DELETE "https://api.solosearch.app/api/v1/search-engines/{uuid}/products/1042" \
-H "Authorization: Bearer your-api-token-here"
This is idempotent — deleting a product that's already gone (or never existed) still returns 200, since the end result is what you asked for either way.
| Status | Meaning |
|---|---|
200 |
Product deleted (or already absent). |
401 |
Invalid or missing token. |
404 |
Search engine not found. |
422 |
The search engine hasn't been indexed yet. |
429 |
Too many requests — limited to 60 per minute. |