Getting started

Quickstart

From a new account to a first search request in six steps, with curl or from your AI agent.

Six steps with curl. If the concepts are new to you, read the Introduction first. Every call after the first two works the same from the cabinet or an MCP client.

Create an account

Register with your email and confirm it from the verification mail. Registration creates an organization, a project called Default and the Free plan for you. Open the project in the cabinet and copy its id from the URL: /app/p/<project id>/….

Create a secret key

In the cabinet, open API keys and create a secret key (zs_sk_…) with full access. The key is shown once, so copy it now. Creating keys needs a confirmed email and the admin role in the organization.

export PROJECT_ID=<project id>
export ZS_KEY=zs_sk_...

Create an index

POST/v1/projects/:projectId/indicesSecret key with full access
curl -X POST https://api.zaproo-search.com/v1/projects/$PROJECT_ID/indices \
  -H "Authorization: Bearer $ZS_KEY" -H "Content-Type: application/json" \
  -d '{"name": "products", "language": "english"}'

The answer is the new index with its id. Leave out fields and the first upload maps every field it can recognise. language sets stemming and stop words; changing it later needs a reindex.

Upload documents

POST/v1/projects/:projectId/indices/:indexId/documentsSecret key with full access

The body is a bare JSON array of up to 1000 documents, each with an id. Writes are asynchronous: the API answers 202 with a task id.

export INDEX_ID=<index id>
curl -X POST https://api.zaproo-search.com/v1/projects/$PROJECT_ID/indices/$INDEX_ID/documents \
  -H "Authorization: Bearer $ZS_KEY" -H "Content-Type: application/json" \
  -d '[
    {"id": "tv-1", "title": "55 inch OLED TV", "brand": "Samsung", "price": 899, "inStock": true},
    {"id": "tv-2", "title": "50 inch LED TV", "brand": "LG", "price": 449, "inStock": true}
  ]'
# 202 {"taskId": "..."}

Poll the task until its status is SUCCEEDED. PARTIAL means some documents failed; the task's errors say which and why.

GET/v1/projects/:projectId/tasks/:taskIdSecret key
curl https://api.zaproo-search.com/v1/projects/$PROJECT_ID/tasks/$TASK_ID -H "Authorization: Bearer $ZS_KEY"

Create a search profile

A search profile fixes which fields a query looks in, the facets and the sort orders. Your storefront only sends the query, filters, sort and page.

POST/v1/projects/:projectId/indices/:indexId/profilesSecret key with full access
curl -X POST https://api.zaproo-search.com/v1/projects/$PROJECT_ID/indices/$INDEX_ID/profiles \
  -H "Authorization: Bearer $ZS_KEY" -H "Content-Type: application/json" \
  -d '{
    "name": "Storefront",
    "queryFields": {"title": 3, "brand": 1},
    "facets": [{"type": "terms", "field": "brand"}],
    "sortOptions": ["_relevance", "price:asc", "price:desc"]
  }'

The answer carries the profile's profileKey, which goes into the public search URL and never changes.

POST/v1/search/:profileKeyPublic key from an allowed origin, or a secret key
curl -X POST https://api.zaproo-search.com/v1/search/$PROFILE_KEY \
  -H "Authorization: Bearer $ZS_KEY" -H "Content-Type: application/json" \
  -d '{"q": "tv", "filters": {"brand": ["Samsung"]}, "page": 1}'

The answer holds items, total, facets with counts and correctedQuery when did-you-mean stepped in. For the storefront, call search from the shopper's browser with a public key (zs_pk_…) that lists your shop's domains, or from your shop's server with a secret key that has read access and is limited to the index. Integrate a storefront shows the search page, facets and autocomplete in full.

Or let your agent do it

Every step above is also an MCP tool. Connect Claude Code or another MCP client with your secret key (see MCP setup) and ask in plain words:

Create an index called products in English, upload the documents in ./catalog.json,
wait for the task to finish, then create a search profile that searches title and brand
with a brand facet, and search for "tv".

The agent calls create_index, index_documents, get_task, upsert_profile and search for you.

Languages

An index has one language for its analyzers. Pick it when you create the index:

Index languages
LanguagelanguageAnalysis
English (US)englishStemming and stop words
BulgarianbulgarianStemming and stop words
CroatiancroatianBasic matching: no word-form reduction
DanishdanishStemming and stop words
DutchdutchStemming and stop words
EstonianestonianStemming and stop words
FinnishfinnishStemming and stop words
FrenchfrenchStemming and stop words
GermangermanStemming and stop words
GreekgreekStemming and stop words
HungarianhungarianStemming and stop words
ItalianitalianStemming and stop words
LatvianlatvianStemming and stop words
NorwegiannorwegianStemming and stop words
PolishpolishStemming and stop words
PortugueseportugueseStemming and stop words
RomanianromanianStemming and stop words
RussianrussianStemming and stop words
SerbianserbianStemming and stop words
SlovenianslovenianBasic matching: no word-form reduction
SpanishspanishStemming and stop words
SwedishswedishStemming and stop words
Language-neutralstandardBasic matching: no word-form reduction