[{"data":1,"prerenderedAt":1281},["ShallowReactive",2],{"docs-navigation":3,"docs-\u002Fdocs\u002Fkeys\u002Fapi-keys":331,"docs-\u002Fdocs\u002Fkeys\u002Fapi-keys-surround":1278},[4],{"title":5,"path":6,"stem":7,"children":8,"page":46},"Docs","\u002Fdocs","docs",[9,47,72,90,132,198,241,252,276,301],{"title":10,"description":11,"icon":12,"path":13,"stem":14,"children":15,"page":46},"Getting started","What Zaproo Search is, a quickstart, and wiring search into a storefront.","i-lucide-rocket","\u002Fdocs\u002Fgetting-started","docs\u002F1.getting-started",[16,22,28,34,40],{"title":17,"path":18,"stem":19,"description":20,"icon":21},"Introduction","\u002Fdocs\u002Fgetting-started\u002Fintroduction","docs\u002F1.getting-started\u002F1.introduction","What Zaproo Search is, the five things you work with, and how a product catalog becomes a search box on your shop.","i-lucide-book-open-text",{"title":23,"path":24,"stem":25,"description":26,"icon":27},"Quickstart","\u002Fdocs\u002Fgetting-started\u002Fquickstart","docs\u002F1.getting-started\u002F2.quickstart","Set up search for your shop in the cabinet, from a new account to a first search, with the API and MCP as other ways to do the same.","i-lucide-zap",{"title":29,"path":30,"stem":31,"description":32,"icon":33},"Integrate a storefront","\u002Fdocs\u002Fgetting-started\u002Fstorefront","docs\u002F1.getting-started\u002F3.storefront","Build a search results page with facets and an autocomplete box on top of the search and suggest routes.","i-lucide-store",{"title":35,"path":36,"stem":37,"description":38,"icon":39},"JavaScript SDK","\u002Fdocs\u002Fgetting-started\u002Fjavascript-sdk","docs\u002F1.getting-started\u002F4.javascript-sdk","Search, autocomplete and event tracking from a storefront with one small client that runs in the browser, on your server and in edge functions.","i-lucide-braces",{"title":41,"path":42,"stem":43,"description":44,"icon":45},"AI shopping assistant","\u002Fdocs\u002Fgetting-started\u002Fai-assistant","docs\u002F1.getting-started\u002F5.ai-assistant","A chat widget for your storefront that finds products and answers questions from your indexes.","i-lucide-sparkles",false,{"title":48,"description":49,"icon":50,"path":51,"stem":52,"children":53,"page":46},"Account and team","Sign-in, sessions, organizations, members, roles and projects.","i-lucide-users","\u002Fdocs\u002Faccount","docs\u002F2.account",[54,60,66],{"title":55,"path":56,"stem":57,"description":58,"icon":59},"Account and sign-in","\u002Fdocs\u002Faccount\u002Fsign-in","docs\u002F2.account\u002F1.sign-in","Create an account, verify your email, stay signed in, manage signed-in devices and change or reset your password.","i-lucide-log-in",{"title":61,"path":62,"stem":63,"description":64,"icon":65},"Organizations, members and roles","\u002Fdocs\u002Faccount\u002Forganizations","docs\u002F2.account\u002F2.organizations","What an organization holds, how to add members, and what owners, admins and members may do.","i-lucide-building-2",{"title":67,"path":68,"stem":69,"description":70,"icon":71},"Projects","\u002Fdocs\u002Faccount\u002Fprojects","docs\u002F2.account\u002F3.projects","Group the indices and API keys of one shop or one environment, and keep staging apart from production.","i-lucide-folder-kanban",{"title":73,"description":74,"icon":75,"path":76,"stem":77,"children":78,"page":46},"API keys and security","Secret and public keys, scopes, allowed origins, rate limits and errors.","i-lucide-key-round","\u002Fdocs\u002Fkeys","docs\u002F3.keys",[79,84],{"title":80,"path":81,"stem":82,"description":83,"icon":75},"API keys","\u002Fdocs\u002Fkeys\u002Fapi-keys","docs\u002F3.keys\u002F1.api-keys","Secret and public keys, full and read access, index scope, allowed origins, expiry, and how to revoke a key.",{"title":85,"path":86,"stem":87,"description":88,"icon":89},"Rate limits and errors","\u002Fdocs\u002Fkeys\u002Frate-limits","docs\u002F3.keys\u002F2.rate-limits","How many requests each route accepts per minute, what a 429 looks like, the error format and every error code with its HTTP status.","i-lucide-gauge",{"title":91,"description":92,"icon":93,"path":94,"stem":95,"children":96,"page":46},"Indexing","Indices, languages, mappings, documents, tasks, full catalog sync and reindexing.","i-lucide-database","\u002Fdocs\u002Findexing","docs\u002F4.indexing",[97,102,108,114,120,126],{"title":98,"path":99,"stem":100,"description":101,"icon":93},"Indices and languages","\u002Fdocs\u002Findexing\u002Findices","docs\u002F4.indexing\u002F1.indices","Create an index, pick its language, read its status, and change the language later with a reindex.",{"title":103,"path":104,"stem":105,"description":106,"icon":107},"Mapping and fields","\u002Fdocs\u002Findexing\u002Fmapping","docs\u002F4.indexing\u002F2.mapping","Field types, the five flags that decide what a field is used for, text analysis options, unmapped fields, and which changes need a reindex.","i-lucide-table-properties",{"title":109,"path":110,"stem":111,"description":112,"icon":113},"Documents and tasks","\u002Fdocs\u002Findexing\u002Fdocuments","docs\u002F4.indexing\u002F3.documents","Upload, browse and delete documents in the cabinet or through the API, follow each write as a task, and retry safely with Idempotency-Key.","i-lucide-file-json",{"title":115,"path":116,"stem":117,"description":118,"icon":119},"Full catalog sync","\u002Fdocs\u002Findexing\u002Ffull-sync","docs\u002F4.indexing\u002F4.full-sync","Replace the whole catalog with a replace session, so products missing from your export disappear from search, without downtime.","i-lucide-refresh-cw",{"title":121,"path":122,"stem":123,"description":124,"icon":125},"Reindex and versions","\u002Fdocs\u002Findexing\u002Fversions","docs\u002F4.indexing\u002F5.versions","Rebuild an index with its saved mapping and swap it in without downtime, follow or cancel the rebuild, and read activeVersion and buildingVersion.","i-lucide-git-compare-arrows",{"title":127,"path":128,"stem":129,"description":130,"icon":131},"Data source","\u002Fdocs\u002Findexing\u002Fdata-source","docs\u002F4.indexing\u002F6.data-source","Let Zaproo download your product feed on a schedule, map it to documents, write only what changed and delete what left the feed.","i-lucide-rss",{"title":133,"description":134,"icon":135,"path":136,"stem":137,"children":138,"page":46},"Integrations","Connect your shop. Magento 2, product feeds and the API work today; more platforms are coming.","i-lucide-plug-zap","\u002Fdocs\u002Fintegrations","docs\u002F4.integrations",[139,145,151,156,162,168,173,178,183,188,193],{"title":140,"path":141,"stem":142,"description":143,"icon":144},"Integrations overview","\u002Fdocs\u002Fintegrations\u002Foverview","docs\u002F4.integrations\u002F01.overview","The ways to get your catalog into Zaproo Search, which one to pick, and how a connected shop shows up in the cabinet.","i-lucide-layout-grid",{"title":146,"path":147,"stem":148,"description":149,"icon":150},"Magento 2","\u002Fdocs\u002Fintegrations\u002Fmagento","docs\u002F4.integrations\u002F02.magento","Install the Zaproo Search module for Magento 2, connect each store view to its own index, and keep the catalog in sync.","i-lucide-shopping-cart",{"title":152,"path":153,"stem":154,"description":155,"icon":131},"Product feed","\u002Fdocs\u002Fintegrations\u002Fproduct-feed","docs\u002F4.integrations\u002F03.product-feed","Connect any shop that can publish its catalog as a feed. You set it up in the cabinet, and Zaproo downloads the feed on a schedule and writes only what changed.",{"title":157,"path":158,"stem":159,"description":160,"icon":161},"REST API and MCP","\u002Fdocs\u002Fintegrations\u002Frest-api-and-mcp","docs\u002F4.integrations\u002F04.rest-api-and-mcp","Send documents from your own code with the REST API, or let an AI agent manage the index over MCP.","i-lucide-code",{"title":163,"path":164,"stem":165,"description":166,"icon":167},"Shopify","\u002Fdocs\u002Fintegrations\u002Fshopify","docs\u002F4.integrations\u002F05.shopify","A Zaproo Search integration for Shopify is coming soon. Until then, connect the shop through a product feed or the REST API.","i-lucide-shopping-bag",{"title":169,"path":170,"stem":171,"description":172,"icon":167},"WooCommerce","\u002Fdocs\u002Fintegrations\u002Fwoocommerce","docs\u002F4.integrations\u002F06.woocommerce","A Zaproo Search integration for WooCommerce is coming soon. Until then, connect the shop through a product feed or the REST API.",{"title":174,"path":175,"stem":176,"description":177,"icon":167},"Shopware","\u002Fdocs\u002Fintegrations\u002Fshopware","docs\u002F4.integrations\u002F07.shopware","A Zaproo Search integration for Shopware is coming soon. Until then, connect the shop through a product feed or the REST API.",{"title":179,"path":180,"stem":181,"description":182,"icon":167},"BigCommerce","\u002Fdocs\u002Fintegrations\u002Fbigcommerce","docs\u002F4.integrations\u002F08.bigcommerce","A Zaproo Search integration for BigCommerce is coming soon. Until then, connect the shop through a product feed or the REST API.",{"title":184,"path":185,"stem":186,"description":187,"icon":167},"PrestaShop","\u002Fdocs\u002Fintegrations\u002Fprestashop","docs\u002F4.integrations\u002F09.prestashop","A Zaproo Search integration for PrestaShop is coming soon. Until then, connect the shop through a product feed or the REST API.",{"title":189,"path":190,"stem":191,"description":192,"icon":167},"commercetools","\u002Fdocs\u002Fintegrations\u002Fcommercetools","docs\u002F4.integrations\u002F10.commercetools","A Zaproo Search integration for commercetools is coming soon. Until then, connect the shop through a product feed or the REST API.",{"title":194,"path":195,"stem":196,"description":197,"icon":167},"Salesforce Commerce Cloud","\u002Fdocs\u002Fintegrations\u002Fsalesforce-commerce-cloud","docs\u002F4.integrations\u002F11.salesforce-commerce-cloud","A Zaproo Search integration for Salesforce Commerce Cloud is coming soon. Until then, connect the shop through a product feed or the REST API.",{"title":199,"description":200,"icon":201,"path":202,"stem":203,"children":204,"page":46},"Search and relevance","The search API, search profiles, facets, synonyms and ranking rules.","i-lucide-search","\u002Fdocs\u002Fsearch","docs\u002F5.search",[205,211,217,223,229,235],{"title":206,"path":207,"stem":208,"description":209,"icon":210},"Search API","\u002Fdocs\u002Fsearch\u002Fsearch-api","docs\u002F5.search\u002F1.search-api","Try a search in the playground, then the search request and response for developers, with every filter form, sorting, paging, highlighting and the inline profile.","i-lucide-search-code",{"title":212,"path":213,"stem":214,"description":215,"icon":216},"Search profiles","\u002Fdocs\u002Fsearch\u002Fprofiles","docs\u002F5.search\u002F2.profiles","Every setting of a search profile, what it does to results, and the mistakes to avoid.","i-lucide-sliders-horizontal",{"title":218,"path":219,"stem":220,"description":221,"icon":222},"Facets","\u002Fdocs\u002Fsearch\u002Ffacets","docs\u002F5.search\u002F3.facets","The filter panels next to the results, the four facet types, index facets and profile facets, and how a shopper's clicks change the counts.","i-lucide-list-filter",{"title":224,"path":225,"stem":226,"description":227,"icon":228},"Synonyms","\u002Fdocs\u002Fsearch\u002Fsynonyms","docs\u002F5.search\u002F4.synonyms","Let different words find the same products, with equivalent and one-way rules, bulk import and export in the Solr format, and no reindex.","i-lucide-arrow-left-right",{"title":230,"path":231,"stem":232,"description":233,"icon":234},"Ranking rules","\u002Fdocs\u002Fsearch\u002Frules","docs\u002F5.search\u002F5.rules","Change the results for chosen searches. Put products first, hide them, lift or lower a brand, narrow the results or weigh fields differently, on a schedule and per profile.","i-lucide-list-ordered",{"title":236,"path":237,"stem":238,"description":239,"icon":240},"Language groups","\u002Fdocs\u002Fsearch\u002Flanguage-groups","docs\u002F5.search\u002F6.language-groups","Let each store of a multilingual shop find its products by the other stores' text, so an English search on the Estonian store still finds the Estonian product.","i-lucide-languages",{"title":242,"description":243,"icon":244,"path":245,"stem":246,"children":247,"page":46},"Autocomplete","Query suggestions as the shopper types.","i-lucide-text-cursor-input","\u002Fdocs\u002Fautocomplete","docs\u002F6.autocomplete",[248],{"title":242,"path":249,"stem":250,"description":251,"icon":244},"\u002Fdocs\u002Fautocomplete\u002Fsuggestions","docs\u002F6.autocomplete\u002F1.suggestions","Set up query suggestions in the cabinet. They are built every hour from your shoppers' searches, field values and custom entries.",{"title":253,"description":254,"icon":255,"path":256,"stem":257,"children":258,"page":46},"Analytics","Searches, zero-result queries and latency.","i-lucide-chart-line","\u002Fdocs\u002Fanalytics","docs\u002F7.analytics",[259,264,270],{"title":260,"path":261,"stem":262,"description":263,"icon":255},"Search analytics","\u002Fdocs\u002Fanalytics\u002Fsearch-analytics","docs\u002F7.analytics\u002F1.search-analytics","What the analytics page counts, which traffic it leaves out, how the headline numbers are defined, how comparisons and retention work, and how to get the weekly digest.",{"title":265,"path":266,"stem":267,"description":268,"icon":269},"Reports","\u002Fdocs\u002Fanalytics\u002Freports","docs\u002F7.analytics\u002F2.reports","Every analytics report with the definition of each column, the opportunities list and its fix buttons, the per-query view with before and after, and the CSV download.","i-lucide-table",{"title":271,"path":272,"stem":273,"description":274,"icon":275},"Event tracking","\u002Fdocs\u002Fanalytics\u002Fevent-tracking","docs\u002F7.analytics\u002F3.event-tracking","Send clicks, add-to-cart, purchases and suggestion clicks from your storefront, tie them to the search with searchId, and a copy-paste script that does it.","i-lucide-mouse-pointer-click",{"title":277,"description":278,"icon":279,"path":280,"stem":281,"children":282,"page":46},"AI agents (MCP)","Connect Claude Code or any MCP client and manage search from an agent.","i-lucide-bot","\u002Fdocs\u002Fmcp","docs\u002F8.mcp",[283,289,295],{"title":284,"path":285,"stem":286,"description":287,"icon":288},"MCP setup","\u002Fdocs\u002Fmcp\u002Fsetup","docs\u002F8.mcp\u002F1.setup","Connect Claude Code or another MCP client to your project from the cabinet's MCP connection page, and let an agent manage indices, documents, profiles, synonyms and rules.","i-lucide-plug",{"title":290,"path":291,"stem":292,"description":293,"icon":294},"MCP tools","\u002Fdocs\u002Fmcp\u002Ftools","docs\u002F8.mcp\u002F2.tools","Every tool the Zaproo Search MCP server offers, what an agent can do with each group, and prompts to start from.","i-lucide-wrench",{"title":296,"path":297,"stem":298,"description":299,"icon":300},"Resources and prompts","\u002Fdocs\u002Fmcp\u002Fresources","docs\u002F8.mcp\u002F3.resources","The index resources an MCP client can read, the tune_relevance prompt, and the errors the MCP server answers.","i-lucide-library",{"title":302,"description":303,"icon":304,"path":305,"stem":306,"children":307,"page":46},"Reference","Every REST route, every limit, plans and billing, and status.","i-lucide-book-open","\u002Fdocs\u002Freference","docs\u002F9.reference",[308,314,319,325],{"title":309,"path":310,"stem":311,"description":312,"icon":313},"REST API","\u002Fdocs\u002Freference\u002Frest-api","docs\u002F9.reference\u002F1.rest-api","The routes of the Zaproo Search REST API, grouped by area, with who may call it.","i-lucide-list-tree",{"title":315,"path":316,"stem":317,"description":318,"icon":89},"Limits","\u002Fdocs\u002Freference\u002Flimits","docs\u002F9.reference\u002F2.limits","Every size limit, cap and default of the Zaproo Search API in one place, with what happens when you reach it.",{"title":320,"path":321,"stem":322,"description":323,"icon":324},"Plans and billing","\u002Fdocs\u002Freference\u002Fbilling","docs\u002F9.reference\u002F3.billing","Check your plan and usage on the Billing & usage page, change the plan, download invoices, and see how quotas and proration work.","i-lucide-credit-card",{"title":326,"path":327,"stem":328,"description":329,"icon":330},"Status","\u002Fdocs\u002Freference\u002Fstatus","docs\u002F9.reference\u002F4.status","The status page and the status route, what each service covers and how to use them in your own monitoring.","i-lucide-activity",{"id":332,"title":80,"body":333,"description":83,"extension":1273,"meta":1274,"navigation":1275,"path":81,"seo":1276,"stem":82,"__hash__":1277},"docs\u002Fdocs\u002F3.keys\u002F1.api-keys.md",{"type":334,"value":335,"toc":1252},"minimark",[336,341,349,352,379,394,397,433,437,504,512,518,521,527,590,593,597,622,672,732,767,924,1004,1008,1026,1029,1033,1066,1069,1078,1085,1088,1092,1116,1120,1140,1142,1147,1154,1158,1175,1179,1222,1226,1248],[337,338,340],"h2",{"id":339},"what-a-key-is","What a key is",[342,343,344,345,348],"p",{},"An API key lets a program call the API without your password: your storefront, a catalog import or an AI agent. Every key belongs to one project and acts only on that project's indices. You create and revoke keys in the cabinet, on the project's ",[346,347,80],"strong",{}," page.",[342,350,351],{},"There are two kinds of keys:",[353,354,355,364],"ul",{},[356,357,358,359,363],"li",{},"A secret key (",[360,361,362],"code",{},"zs_sk_…",") is for your servers, scripts and AI agents. It can call every project route its access allows, the search and suggest routes, and the MCP server.",[356,365,366,367,370,371,374,375,378],{},"A public key (",[360,368,369],{},"zs_pk_…",") is meant for browsers. It can only call ",[360,372,373],{},"POST \u002Fv1\u002Fsearch\u002F\u003CprofileKey>"," and ",[360,376,377],{},"POST \u002Fv1\u002Fsuggest\u002F\u003CsuggestKey>"," for the project's indices, and only from the web origins you list.",[342,380,381,382,385,386,389,390,393],{},"The browser sends the page's ",[360,383,384],{},"Origin"," header with every call. A public key used from a server has none and gets ",[360,387,388],{},"403 ORIGIN_NOT_ALLOWED",", so servers use a secret key with read access, limited to the index. See ",[391,392,29],"a",{"href":30},".",[342,395,396],{},"A program sends the key as a bearer token:",[398,399,404],"pre",{"className":400,"code":401,"language":402,"meta":403,"style":403},"language-bash shiki shiki-themes github-light-high-contrast github-light-high-contrast github-dark-high-contrast","curl https:\u002F\u002Fapi.search.zaproo.cloud\u002Fv1\u002Fprojects\u002F$PROJECT_ID\u002Findices -H \"Authorization: Bearer zs_sk_...\"\n","bash","",[360,405,406],{"__ignoreMap":403},[407,408,411,415,419,423,426,430],"span",{"class":409,"line":410},"line",1,[407,412,414],{"class":413},"szw1H","curl",[407,416,418],{"class":417},"semJd"," https:\u002F\u002Fapi.search.zaproo.cloud\u002Fv1\u002Fprojects\u002F",[407,420,422],{"class":421},"s7iLA","$PROJECT_ID",[407,424,425],{"class":417},"\u002Findices",[407,427,429],{"class":428},"ssYy9"," -H",[407,431,432],{"class":417}," \"Authorization: Bearer zs_sk_...\"\n",[337,434,436],{"id":435},"create-a-key","Create a key",[438,439,440,446,452,462,476,487,494],"ol",{},[356,441,442,443,445],{},"Open the project and click ",[346,444,80],{}," in the sidebar.",[356,447,448,449,393],{},"Click ",[346,450,451],{},"New key",[356,453,454,455,458,459,393],{},"In the ",[346,456,457],{},"New API key"," dialog, enter a ",[346,460,461],{},"Name",[356,463,464,465,468,469,472,473,393],{},"Pick the ",[346,466,467],{},"Type",": ",[346,470,471],{},"Secret key (sk), server side"," or ",[346,474,475],{},"Public key (pk), browser side",[356,477,464,478,468,481,472,484,393],{},[346,479,480],{},"Access",[346,482,483],{},"Full access",[346,485,486],{},"Read only",[356,488,489,490,493],{},"For a public key, list your shop's domains under ",[346,491,492],{},"Allowed origins",", one per line.",[356,495,448,496,499,500,393],{},[346,497,498],{},"Create key",", then copy the key. It is ",[391,501,503],{"href":502},"#the-key-is-shown-once","shown only once",[342,505,506],{},[507,508],"img",{"alt":509,"src":510,"title":511},"The New API key dialog with a Name field, the Type set to Secret key (sk), server side and the Access set to Full access, over the list of keys","\u002Fdocs\u002Fscreenshots\u002Fapi-keys.png","The New API key dialog",[342,513,514,515,517],{},"Creating keys needs the admin or owner role and a verified email. Until then ",[346,516,451],{}," stays off and the page says why. Only a signed-in person can create keys. A key cannot create other keys, so this step always happens in the cabinet.",[342,519,520],{},"The cabinet form sets the name, type, access and allowed origins. The cabinet has no control for index scope or expiry; set them through the API:",[522,523],"api-route",{"auth":524,"method":525,"path":526},"Admin or owner with a verified email, not while support is acting as you","POST","\u002Fv1\u002Fprojects\u002F:projectId\u002Fapi-keys",[398,528,530],{"className":400,"code":529,"language":402,"meta":403,"style":403},"curl -X POST https:\u002F\u002Fapi.search.zaproo.cloud\u002Fv1\u002Fprojects\u002F$PROJECT_ID\u002Fapi-keys \\\n  -H \"Authorization: Bearer $ACCESS_TOKEN\" -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"name\": \"Storefront server\", \"kind\": \"SECRET\", \"access\": \"READ\", \"indexScope\": [\"'$INDEX_ID'\"]}'\n",[360,531,532,553,575],{"__ignoreMap":403},[407,533,534,536,539,542,544,546,549],{"class":409,"line":410},[407,535,414],{"class":413},[407,537,538],{"class":428}," -X",[407,540,541],{"class":417}," POST",[407,543,418],{"class":417},[407,545,422],{"class":421},[407,547,548],{"class":417},"\u002Fapi-keys",[407,550,552],{"class":551},"sklAV"," \\\n",[407,554,556,559,562,565,568,570,573],{"class":409,"line":555},2,[407,557,558],{"class":428},"  -H",[407,560,561],{"class":417}," \"Authorization: Bearer ",[407,563,564],{"class":421},"$ACCESS_TOKEN",[407,566,567],{"class":417},"\"",[407,569,429],{"class":428},[407,571,572],{"class":417}," \"Content-Type: application\u002Fjson\"",[407,574,552],{"class":551},[407,576,578,581,584,587],{"class":409,"line":577},3,[407,579,580],{"class":428},"  -d",[407,582,583],{"class":417}," '{\"name\": \"Storefront server\", \"kind\": \"SECRET\", \"access\": \"READ\", \"indexScope\": [\"'",[407,585,586],{"class":421},"$INDEX_ID",[407,588,589],{"class":417},"'\"]}'\n",[342,591,592],{},"The API call needs your cabinet session's access token, not an API key.",[337,594,596],{"id":595},"key-settings","Key settings",[598,599,603,608,611],"setting",{"name":600,"type":601,"values":602},"name","string","1 to 100 characters",[604,605,607],"h3",{"id":606},"key-name","Key name",[342,609,610],{},"What the key is for. The name shows in the key list, next to the key's prefix.",[612,613,614],"template",{"v-slot:tips":403},[353,615,616,619],{},[356,617,618],{},"Name a key after the program that uses it (\"Storefront server\", \"Nightly catalog import\"). When you need to revoke one, you know which program stops working.",[356,620,621],{},"Create one key per program. Sharing a key means revoking it breaks every program at once.",[598,623,626,630,653,663],{"name":624,"type":625},"kind","SECRET | PUBLIC",[604,627,629],{"id":628},"key-type","Key type",[342,631,632,635,636,638,639,642,643,635,646,648,649,652],{},[360,633,634],{},"SECRET"," (",[346,637,471],{}," in the cabinet) creates a ",[360,640,641],{},"zs_sk_"," key for servers. ",[360,644,645],{},"PUBLIC",[346,647,475],{},") creates a ",[360,650,651],{},"zs_pk_"," key for browsers that can only search and suggest. The type cannot change later. Create a new key instead.",[612,654,655],{"v-slot:tips":403},[353,656,657,660],{},[356,658,659],{},"Never put a secret key in frontend code, a mobile app or a public repository. Anyone who reads it can act on your project with its access.",[356,661,662],{},"A public key sent to any route other than search and suggest is refused.",[612,664,665],{"v-slot:related":403},[353,666,667],{},[356,668,669],{},[391,670,492],{"href":671},"#allowed-origins",[598,673,677,679,695,723],{"name":674,"type":675,"default":676},"access","FULL | READ","FULL",[604,678,480],{"id":674},[342,680,681,635,683,685,686,635,689,691,692,694],{},[360,682,676],{},[346,684,483],{}," in the cabinet) can read and change everything in the project: indices, mappings, documents, profiles, synonyms, rules and autocomplete. ",[360,687,688],{},"READ",[346,690,486],{},") can read all of that and search, but changes nothing. A public key always has ",[360,693,688],{},", whatever you pick.",[612,696,697],{"v-slot:tips":403},[353,698,699,705,714],{},[356,700,701,702,704],{},"Give a server that only searches a ",[360,703,688],{}," key. If the key leaks, nobody can delete your indices with it.",[356,706,707,708,710,711,713],{},"Give your catalog import and your AI agent a ",[360,709,676],{}," key. An agent with a ",[360,712,688],{}," key can call only the read tools.",[356,715,716,717,719,720,393],{},"A ",[360,718,688],{}," key on a write route answers ",[360,721,722],{},"403 FORBIDDEN",[612,724,725],{"v-slot:related":403},[353,726,727],{},[356,728,729],{},[391,730,61],{"href":731},"\u002Fdocs\u002Faccount\u002Forganizations#what-each-role-may-do",[598,733,738,742,753],{"name":734,"type":735,"default":736,"values":737},"indexScope","index id list","[] (every index)","up to 100 index ids",[604,739,741],{"id":740},"index-scope","Index scope",[342,743,744,745,748,749,752],{},"Limits the key to the listed indices of the project. Set it through the API; the cabinet form has no field for it. An empty list means every index, including indices created later. To the key, an index outside its scope does not exist. Its routes answer ",[360,746,747],{},"404 INDEX_NOT_FOUND",", it is missing from the index list, and its tasks are missing from the task list. Search and suggest with a profile or suggest key of such an index answer ",[360,750,751],{},"404"," too.",[612,754,755],{"v-slot:tips":403},[353,756,757,760],{},[356,758,759],{},"Scope the key of a storefront server to the one index it searches.",[356,761,762,763,766],{},"A scoped key cannot create indices. It answers ",[360,764,765],{},"403 INDEX_SCOPED_KEY",", because the key could not see the new index.",[598,768,772,775,787,819,895,898],{"name":769,"type":770,"values":771},"allowedOrigins","origin list","up to 50; required for a public key",[604,773,492],{"id":774},"allowed-origins",[342,776,777,778,780,781,783,784,786],{},"The web origins a public key works from. On every request with a public key, the API compares the request's ",[360,779,384],{}," header with this list. A request whose origin is not on the list, or that has no ",[360,782,384],{}," header, answers ",[360,785,388],{},". A secret key ignores the list.",[342,788,789,790,472,793,796,797,799,800,472,803,806,807,810,811,814,815,818],{},"Write each origin as ",[360,791,792],{},"scheme:\u002F\u002Fhost",[360,794,795],{},"scheme:\u002F\u002Fhost:port",", in lower case, with no path and no trailing slash. In the cabinet's ",[346,798,457],{}," dialog you may type just the domain, ",[360,801,802],{},"shop.example.com",[360,804,805],{},"*.shop.example.com",", and it is saved as its ",[360,808,809],{},"https:\u002F\u002F"," origin in lower case. Type ",[360,812,813],{},"http:\u002F\u002F"," origins, such as ",[360,816,817],{},"http:\u002F\u002Flocalhost:3000",", in full:",[820,821,822,838],"table",{},[823,824,825],"thead",{},[826,827,828,832,835],"tr",{},[829,830,831],"th",{},"Entry",[829,833,834],{},"Matches",[829,836,837],{},"Does not match",[839,840,841,862,880],"tbody",{},[826,842,843,849,853],{},[844,845,846],"td",{},[360,847,848],{},"https:\u002F\u002Fshop.example.com",[844,850,851],{},[360,852,848],{},[844,854,855,858,859],{},[360,856,857],{},"https:\u002F\u002Fwww.shop.example.com",", ",[360,860,861],{},"http:\u002F\u002Fshop.example.com",[826,863,864,869,876],{},[844,865,866],{},[360,867,868],{},"https:\u002F\u002F*.shop.example.com",[844,870,871,858,873],{},[360,872,857],{},[360,874,875],{},"https:\u002F\u002Feu.m.shop.example.com",[844,877,878],{},[360,879,848],{},[826,881,882,886,890],{},[844,883,884],{},[360,885,817],{},[844,887,888],{},[360,889,817],{},[844,891,892],{},[360,893,894],{},"http:\u002F\u002Flocalhost:3001",[342,896,897],{},"In the cabinet, enter one origin per line. The key list shows a key's origins under its type.",[612,899,900],{"v-slot:tips":403},[353,901,902,912,918],{},[356,903,904,905,907,908,374,910,393],{},"A wildcard covers subdomains only. To allow ",[360,906,848],{}," and its subdomains, list both ",[360,909,848],{},[360,911,868],{},[356,913,914,915,917],{},"The scheme and the port must match. List ",[360,916,817],{}," separately for local development, and keep it off production keys.",[356,919,920,921,923],{},"Allowed origins are not a secret. Anyone can send any ",[360,922,384],{}," header from a script, so they stop other websites, not scripts.",[598,925,929,933,940,994],{"name":926,"type":927,"default":928},"expiresAt","ISO 8601 date-time","none (never expires)",[604,930,932],{"id":931},"expiry","Expiry",[342,934,935,936,939],{},"The moment the key stops working. Set it through the API; the cabinet form has no field for it. After it, every request with the key answers ",[360,937,938],{},"401 API_KEY_EXPIRED",". Leave it out for a key that never expires.",[398,941,945],{"className":942,"code":943,"language":944,"meta":403,"style":403},"language-json shiki shiki-themes github-light-high-contrast github-light-high-contrast github-dark-high-contrast","{ \"name\": \"Agency access\", \"kind\": \"SECRET\", \"access\": \"READ\", \"expiresAt\": \"2026-12-31T23:59:59Z\" }\n","json",[360,946,947],{"__ignoreMap":403},[407,948,949,952,956,958,961,963,966,968,971,973,976,978,981,983,986,988,991],{"class":409,"line":410},[407,950,951],{"class":421},"{ ",[407,953,955],{"class":954},"sb7M8","\"name\"",[407,957,468],{"class":421},[407,959,960],{"class":417},"\"Agency access\"",[407,962,858],{"class":421},[407,964,965],{"class":954},"\"kind\"",[407,967,468],{"class":421},[407,969,970],{"class":417},"\"SECRET\"",[407,972,858],{"class":421},[407,974,975],{"class":954},"\"access\"",[407,977,468],{"class":421},[407,979,980],{"class":417},"\"READ\"",[407,982,858],{"class":421},[407,984,985],{"class":954},"\"expiresAt\"",[407,987,468],{"class":421},[407,989,990],{"class":417},"\"2026-12-31T23:59:59Z\"",[407,992,993],{"class":421}," }\n",[612,995,996],{"v-slot:tips":403},[353,997,998,1001],{},[356,999,1000],{},"Give a temporary key to an agency or a contractor with an expiry date, so access ends on its own.",[356,1002,1003],{},"An expired key stays in the list, and you cannot extend it. Create a new key.",[337,1005,1007],{"id":1006},"the-key-is-shown-once","The key is shown once",[342,1009,1010,1011,1014,1015,1018,1019,1022,1023,393],{},"The full key appears only once, right after you create it. The cabinet shows it in a box titled ",[346,1012,1013],{},"Your new API key",". Click ",[346,1016,1017],{},"Copy key",", paste the key into your secret store, then click ",[346,1020,1021],{},"I have saved it",". Through the API, the answer to the create request is the only time the full key appears. Zaproo stores only a hash of the key and its first 14 characters, the prefix you see in the list, for example ",[360,1024,1025],{},"zs_sk_Ab3dE9xQ…",[342,1027,1028],{},"If you lose a key, revoke it and create a new one.",[337,1030,1032],{"id":1031},"list-keys","List keys",[342,1034,1035,1036,1038,1039,858,1041,1044,1045,635,1047,472,1050,1053,1054,635,1056,472,1059,1062,1063,393],{},"The ",[346,1037,80],{}," page lists the project's keys, and every member of the organization can see it. The columns are ",[346,1040,461],{},[346,1042,1043],{},"Key"," (the prefix), ",[346,1046,467],{},[360,1048,1049],{},"sk",[360,1051,1052],{},"pk"," with the access, and the allowed origins below) ",[346,1055,326],{},[346,1057,1058],{},"Active",[346,1060,1061],{},"Revoked",") and ",[346,1064,1065],{},"Last used",[604,1067,1065],{"id":1068},"last-used",[342,1070,1071,1073,1074,1077],{},[346,1072,1065],{}," shows when the key last made a request: \"2 h ago\" or \"3 days ago\" for recent use, the date from a week on, and ",[346,1075,1076],{},"Never"," for a key that has made no request yet. Hover over the time to see the exact date and time. The time is updated about once a minute, so a key you just tried can take a minute to show it.",[342,1079,1080,1081,1084],{},"An active key that has made no request for 30 days or more gets a line under the time, such as ",[346,1082,1083],{},"Not used for 45 days",". For a key that was never used, the days count from the day it was created. Such a key often belongs to an old integration or a test. If nothing should use it any more, revoke it. A forgotten key still works for anyone who finds it. Revoked keys never get the line.",[342,1086,1087],{},"With the API:",[522,1089],{"auth":1090,"method":1091,"path":526},"Any member of the organization","GET",[342,1093,1094,1095,858,1097,858,1099,858,1102,374,1105,1108,1109,1111,1112,1115],{},"Through the API, each key also has its ",[360,1096,734],{},[360,1098,926],{},[360,1100,1101],{},"revokedAt",[360,1103,1104],{},"createdAt",[360,1106,1107],{},"lastUsedAt",". ",[360,1110,1107],{}," is ",[360,1113,1114],{},"null"," until the key's first request, and it is updated about once a minute, not on every request.",[337,1117,1119],{"id":1118},"revoke-a-key","Revoke a key",[342,1121,1122,1123,1125,1126,1129,1130,1133,1134,1136,1137,1139],{},"On ",[346,1124,80],{},", click ",[346,1127,1128],{},"Revoke"," in the key's row. There is no confirmation step, and the key stops working at once. The very next request with it answers ",[360,1131,1132],{},"401 API_KEY_REVOKED",". A revoked key stays in the list with the status ",[346,1135,1061],{},", and it cannot be turned back on. Only owners and admins see the ",[346,1138,1128],{}," button.",[342,1141,1087],{},[522,1143],{"auth":1144,"method":1145,"path":1146},"Admin or owner of the organization","DELETE","\u002Fv1\u002Fprojects\u002F:projectId\u002Fapi-keys\u002F:keyId",[342,1148,1149,1150,1153],{},"Revoking a key that is already revoked answers ",[360,1151,1152],{},"204"," again and changes nothing.",[604,1155,1157],{"id":1156},"replace-a-key-without-downtime","Replace a key without downtime",[438,1159,1160,1163,1166],{},[356,1161,1162],{},"Create a new key with the same settings.",[356,1164,1165],{},"Put the new key into your program and deploy it.",[356,1167,1168,1169,1171,1172,1174],{},"Wait until the old key's ",[346,1170,1065],{}," stops moving, then click ",[346,1173,1128],{}," on it. Give it a few minutes after the deploy, since the time is updated about once a minute.",[337,1176,1178],{"id":1177},"common-mistakes","Common mistakes",[353,1180,1181,1187,1190,1203,1219],{},[356,1182,1183,1184,1186],{},"Revoking a key by its name alone. Two keys can share a name. Check the prefix and ",[346,1185,1065],{}," before you revoke one.",[356,1188,1189],{},"Calling project routes with a public key. A public key only searches and suggests. Use a secret key for everything else.",[356,1191,1192,1193,1195,1196,1198,1199,1202],{},"Testing a public key with curl and no ",[360,1194,384],{}," header. The API answers ",[360,1197,388],{},". Add ",[360,1200,1201],{},"-H \"Origin: https:\u002F\u002Fshop.example.com\""," with one of the key's origins.",[356,1204,1205,1206,374,1209,1212,1213,1216,1217,393],{},"Writing origins with a path or a trailing slash. ",[360,1207,1208],{},"https:\u002F\u002Fshop.example.com\u002F",[360,1210,1211],{},"https:\u002F\u002Fshop.example.com\u002Fsearch"," are refused with ",[360,1214,1215],{},"400 VALIDATION_FAILED",". Write ",[360,1218,848],{},[356,1220,1221],{},"Keeping a key after the person who set it up left. Keys belong to the project, not to a person. Revoke the keys that person knew.",[337,1223,1225],{"id":1224},"related","Related",[353,1227,1228,1232,1236,1240,1244],{},[356,1229,1230],{},[391,1231,85],{"href":86},[356,1233,1234],{},[391,1235,61],{"href":731},[356,1237,1238],{},[391,1239,23],{"href":24},[356,1241,1242],{},[391,1243,29],{"href":30},[356,1245,1246],{},[391,1247,284],{"href":285},[1249,1250,1251],"style",{},"html pre.shiki code .szw1H, html code.shiki .szw1H{--shiki-light:#702C00;--shiki-default:#702C00;--shiki-dark:#FFB757}html pre.shiki code .semJd, html code.shiki .semJd{--shiki-light:#032563;--shiki-default:#032563;--shiki-dark:#ADDCFF}html pre.shiki code .s7iLA, html code.shiki .s7iLA{--shiki-light:#0E1116;--shiki-default:#0E1116;--shiki-dark:#F0F3F6}html pre.shiki code .ssYy9, html code.shiki .ssYy9{--shiki-light:#023B95;--shiki-default:#023B95;--shiki-dark:#91CBFF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sklAV, html code.shiki .sklAV{--shiki-light:#A0111F;--shiki-default:#A0111F;--shiki-dark:#FF9492}html pre.shiki code .sb7M8, html code.shiki .sb7M8{--shiki-light:#024C1A;--shiki-default:#024C1A;--shiki-dark:#72F088}",{"title":403,"searchDepth":555,"depth":555,"links":1253},[1254,1255,1256,1264,1265,1268,1271,1272],{"id":339,"depth":555,"text":340},{"id":435,"depth":555,"text":436},{"id":595,"depth":555,"text":596,"children":1257},[1258,1259,1260,1261,1262,1263],{"id":606,"depth":577,"text":607},{"id":628,"depth":577,"text":629},{"id":674,"depth":577,"text":480},{"id":740,"depth":577,"text":741},{"id":774,"depth":577,"text":492},{"id":931,"depth":577,"text":932},{"id":1006,"depth":555,"text":1007},{"id":1031,"depth":555,"text":1032,"children":1266},[1267],{"id":1068,"depth":577,"text":1065},{"id":1118,"depth":555,"text":1119,"children":1269},[1270],{"id":1156,"depth":577,"text":1157},{"id":1177,"depth":555,"text":1178},{"id":1224,"depth":555,"text":1225},"md",{},{"icon":75},{"title":80,"description":83},"mjUuGyzvfKXaed4kIm6VsNrLQZFYe4-6XKehr6Vcp6w",[1279,1280],{"title":67,"path":68,"stem":69,"description":70,"icon":71,"children":-1},{"title":85,"path":86,"stem":87,"description":88,"icon":89,"children":-1},1793717706302]