{"id":47917843,"url":"https://github.com/addsearch/js-client-library","last_synced_at":"2026-04-13T13:01:14.356Z","repository":{"id":34906865,"uuid":"186605980","full_name":"AddSearch/js-client-library","owner":"AddSearch","description":"JavaScript client library for AddSearch REST API","archived":false,"fork":false,"pushed_at":"2026-04-13T08:35:15.000Z","size":1202,"stargazers_count":5,"open_issues_count":3,"forks_count":1,"subscribers_count":4,"default_branch":"master","last_synced_at":"2026-04-13T10:31:28.028Z","etag":null,"topics":["addsearch","javascript","search","search-api","search-as-you-type","search-engine","site-search"],"latest_commit_sha":null,"homepage":"https://www.addsearch.com/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/AddSearch.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2019-05-14T11:12:06.000Z","updated_at":"2026-03-20T08:10:36.000Z","dependencies_parsed_at":"2024-02-23T12:23:39.260Z","dependency_job_id":"65b10a40-80e9-43e6-8156-97194cef05c0","html_url":"https://github.com/AddSearch/js-client-library","commit_stats":{"total_commits":211,"total_committers":5,"mean_commits":42.2,"dds":0.2417061611374408,"last_synced_commit":"bcc5949e78f0e2a9125a76017f4e12ad01076cc1"},"previous_names":[],"tags_count":66,"template":false,"template_full_name":null,"purl":"pkg:github/AddSearch/js-client-library","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AddSearch%2Fjs-client-library","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AddSearch%2Fjs-client-library/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AddSearch%2Fjs-client-library/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AddSearch%2Fjs-client-library/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/AddSearch","download_url":"https://codeload.github.com/AddSearch/js-client-library/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AddSearch%2Fjs-client-library/sbom","scorecard":{"id":8635,"data":{"date":"2025-08-11","repo":{"name":"github.com/AddSearch/js-client-library","commit":"5976768ec879136cb723549bfc4c31f2f179ac54"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":6.6,"checks":[{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Maintained","score":10,"reason":"16 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Code-Review","score":10,"reason":"all changesets reviewed","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/publish_github_package.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Pinned-Dependencies","score":3,"reason":"dependency not pinned by hash detected -- score normalized to 3","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/publish_github_package.yml:13: update your workflow using https://app.stepsecurity.io/secureworkflow/AddSearch/js-client-library/publish_github_package.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/publish_github_package.yml:18: update your workflow using https://app.stepsecurity.io/secureworkflow/AddSearch/js-client-library/publish_github_package.yml/master?enable=pin","Info:   0 out of   2 GitHub-owned GitHubAction dependencies pinned","Info:   1 out of   1 npmCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":6,"reason":"branch protection is not maximal on development and all release branches","details":["Info: 'allow deletion' disabled on branch 'master'","Info: 'force pushes' disabled on branch 'master'","Info: 'branch protection settings apply to administrators' is required to merge on branch 'master'","Warn: required approving review count is 1 on branch 'master'","Warn: codeowners review is not required on branch 'master'","Warn: no status checks found to merge onto branch 'master'","Info: PRs are required in order to make changes on branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Packaging","score":10,"reason":"packaging workflow detected","details":["Info: Project packages its releases by way of GitHub Actions.: .github/workflows/publish_github_package.yml:9"],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"SAST","score":5,"reason":"SAST tool is not run on all commits -- score normalized to 5","details":["Warn: 16 commits out of 30 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-14T14:06:15.222Z","repository_id":34906865,"created_at":"2025-08-14T14:06:15.222Z","updated_at":"2025-08-14T14:06:15.222Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31753551,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-13T09:16:15.125Z","status":"ssl_error","status_checked_at":"2026-04-13T09:16:05.023Z","response_time":93,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["addsearch","javascript","search","search-api","search-as-you-type","search-engine","site-search"],"created_at":"2026-04-04T05:47:07.111Z","updated_at":"2026-04-13T13:01:14.350Z","avatar_url":"https://github.com/AddSearch.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# AddSearch Search API Client for JavaScript\n\n[AddSearch](https://www.addsearch.com) is a Search-as-a-Service for all your search needs. This API\nClient lets you easily use the [Search API](https://www.addsearch.com/docs/api/) and\n[Indexing API](https://www.addsearch.com/docs/api/indexing-overview/) with JavaScript.\n\n## Quick Start\n\nThe library is available on the global CDN\n[jsDelivr:](https://www.jsdelivr.com/package/npm/addsearch-js-client)\n\n```html\n\u003cscript src=\"https://cdn.jsdelivr.net/npm/addsearch-js-client@0.6/dist/addsearch-js-client.min.js\"\u003e\u003c/script\u003e\n```\n\nOr install the library locally to use it with Node.js:\n\n```sh\nnpm install addsearch-js-client --save\n```\n\nAfter installation, add the library to your JS code\n\n```js\nvar AddSearchClient = require('addsearch-js-client');\n```\n\nOr use import in ES6\n\n```js\nimport AddSearchClient from 'addsearch-js-client';\n```\n\n#### Execute the first search query\n\n```js\n// Create client with your 32-character SITEKEY\nvar client = new AddSearchClient('YOUR PUBLIC SITEKEY');\n\n// Callback function\nvar cb = function (res) {\n  // Print results to console\n  console.log(res);\n};\n\n// Execute search. Callback function will be called with search results\nclient.search('keyword', cb);\n```\n\n## Search API\n\nThe client provides following functions to execute search queries. To use the client library for\nindexing, see [Indexing API](https://github.com/AddSearch/js-client-library#indexing-api).\n\n#### Fetch search results\n\n```js\n// Search with a specific keyword\nclient.search('keyword', callback);\n\n// Search with the previously used keyword or execute a \"match all\" query\nclient.search(callback);\n\n// Search with the previously used keyword and callback (e.g. after modifying filters)\nclient.search();\n```\n\n#### Fetch search suggestions\n\nSearch suggestions are keywords and search phrases that real users have used in your search.\nConfigure Search suggestions on AddSearch Dashboard before using this function.\n\n```js\n// Get suggestions starting with a specific prefix\nclient.suggestions('a', callback);\n```\n\n#### Set the number of search suggestions to fetch\n\n```js\n// Number of search suggestions to fetch (default 10)\nclient.setSuggestionsSize(20);\n```\n\n#### Custom field autocompletion\n\nCustom fields autocomplete can be used for predictive search. For example, product names or\ncategories can be suggested as the keyword is being typed in.\n\n```js\n// Fetch custom field values starting with a specific prefix In this example, fetch records\n// starting with *a* from the *custom_fields.brand* field. Results could be \"adidas, apple, azure\"\nclient.autocomplete('custom_fields.brand', 'a', callback);\n```\n\n#### Set the number of custom field autocompletion results to fetch\n\n```js\n// Number of autocompletion results to fetch (default 10)\nclient.setAutocompleteSize(20);\n```\n\n#### Search with fuzzy matching\n\nFuzzy matching is used for typo tolerance. There are four options:\n\n- **false**: No typo tolerance\n- **true**: Exact matches and fuzzy matches are equal\n- **\"auto\"**: Exact matches first, followed by fuzzy matches\n- **\"retry\"**: Show exact matches only. If none were found, show fuzzy matches\n\n```js\n// Control fuzzy matching used for typo-tolerance\n// Possible values true/false/\"auto\"/\"retry\" (default: \"auto\")\nclient.setFuzzyMatch(false);\n```\n\n#### Search operator\n\nWhen a user searches with multiple keywords, we return only documents that contain all the terms\nwhich means applying the logical operator AND for the query. It is possible to choose which logical\noperator to use for fuzzy results when the fuzzy parameter is set to auto. There are two options:\n\n- **\"or\"**: makes fuzzy results broader and includes partial matches of a few search terms\n- **\"and\"**: makes fuzzy results stricter and includes only mistyped search terms\n\n```js\n// Possible values \"and\"/\"or\" (default: \"or\")\nclient.setSearchOperator('and');\n```\n\n#### Postfix wildcard\n\nEnable or disable postfix wildcard. I.e. should keyword \"add\" match to \"addsearch\" or should it just\nmatch to the term **add**\n\n```js\n// Possible values true/false (default: true)\nclient.setPostfixWildcard(false);\n```\n\n#### Set enableLogicalOperators\n\n```js\n// (default: false)\n// enableLogicalOperators(true) = Support user specified logical operators (and/or/not) in the search query like \"cat and dog\"\n// enableLogicalOperators(false) = Treat logical operators in the search query as literal strings\nclient.enableLogicalOperators(true);\n```\n\n#### Set cacheResponseTime\n\nCaching the response, define the time-to-live of the cache.\n\n```js\n// Specify time-to-live value in seconds\nclient.setCacheResponseTime(3600);\n```\n\nPlease contact our\n[Support](https://github.com/AddSearch/js-client-library?tab=readme-ov-file#support) team to active\nResponse Caching for your index.\n\n### Pagination\n\nSet page number, page size and sorting parameters. It's possible to order results by:\n\n- relevance (descending)\n- date (ascending or descending)\n- custom field value (ascending or descending. E.g. _custom_fields.price_)\n\nType of sortBy and sortOrder: `string` or `array`. They must have the same type, in case type is\narray, sortBy and sortOrder must have the same size. For example:\n\n```js\nsortBy = 'date';\nsortOrder = 'desc';\n\nor;\n\nsortBy = ['date', 'custom_fields.price'];\nsortOrder = ['desc', 'asc'];\n```\n\n```js\n// Defaults: page: 1, pageSize: 10, sortBy: \"relevance\", sortOrder: \"desc\"\nclient.setPaging(page, pageSize, sortBy, sortOrder);\n```\n\nOther functions.\n\n```js\n// Next page (call search function to fetch results)\nclient.nextPage();\n\n// Previous page\nclient.previousPage();\n```\n\n### Filters\n\n#### Define language filter\n\n```js\n// Fetch documents in specific language (e.g. \"en\" or \"de\" or \"en-GB\")\nclient.setLanguage('en');\n```\n\n#### Define publishing date filter\n\n```js\n// Documents published between specific date range\nclient.setDateFilter('2019-01-01', '2019-01-31');\n```\n\n#### Define price range filter\n\n```js\n// Products in specific price range (in cents. e.g. 100,00 - 200,00)\nclient.setPriceRangeFilter('10000', '20000');\n```\n\n#### Define category filters\n\nFilter by URL patterns, document types or _addsearch-category_ meta tag values. See the\n[full documentation.](https://www.addsearch.com/support/documentation/ranking-relevance-filters/filters/#category-filters)\n\n```js\n// Only PDF files or products\nclient.setCategoryFilters('doctype_pdf,products');\n```\n\n#### Custom field filters\n\nFilter by custom fields. Custon fields can be defined in meta tags or AddSearch crawler can pick\nthem up from your HTML or JSON data. See the\n[full documentation.](https://www.addsearch.com/support/documentation/ranking-relevance-filters/custom-field/)\n\n```js\n// Search by specific city (Berlin, Paris or Boston)\nclient.addCustomFieldFilter('city', 'berlin');\nclient.addCustomFieldFilter('city', 'paris');\nclient.addCustomFieldFilter('city', 'boston');\n\n// Remove Paris (Berlin and Boston remaining)\nclient.removeCustomFieldFilter('city', 'paris');\n\n// Remove all cities\nclient.removeCustomFieldFilter('city');\n```\n\n#### Set filtering object\n\nSet complex filtering object that can contain nested _and_, _or_, _not_, and _range_ filters.\n\n```js\n// Find results where brand is apple, color is not white, and price is between 200 and 500\nvar filter = {\n  and: [\n    { 'custom_fields.brand': 'apple' },\n    { not: { 'custom_fields.color': 'white' } },\n    { range: { 'custom_fields.price': { gt: 200, lt: 500 } } }\n  ]\n};\n\nclient.setFilterObject(filter);\n```\n\n#### Set result type\n\n```js\n// By default, fetch all search results\n// If \"organic\", Pinned results and Promotions are left out\nclient.setResultType('organic');\n```\n\n### Facets\n\n```js\n// Declare fields for faceting. Number of hits found from\n// these fields will be returned\nclient.addFacetField('category');\nclient.addFacetField('custom_fields.genre');\n```\n\nBy default, 10 facets with most hits are returned per field. Use the following function to get more\nor less facets.\n\n```js\nclient.setNumberOfFacets(20);\n```\n\n#### Numerical range facets\n\nGroup numerical custom fields into range buckets.\n\n```js\n// Define ranges. E.g. products with price $0-$100, $100-$200, and over $200.\n// From value is inclusive, to value is exclusive\nvar ranges = [{ to: 100 }, { from: 100, to: 200 }, { from: 200 }];\n\n// Parameters: field name, range array\nclient.addRangeFacet('custom_fields.price', ranges);\n```\n\n### Field statistics\n\nGet minimum, maximum, and average values of a numerical or date-based custom field. The information\nis handy for applications like range filtering.\n\n```js\n// Search response will have a fieldStats element with information like\n// custom_fields.price: {min: 1230, max: 1590, avg: 1382}\nclient.addStatsField('custom_fields.price');\n```\n\n### Recommendations\n\n#### Frequently bought together items\n\nGet frequently bought together items, given \"configurationKey\" and \"itemId\"\n\n```js\n// fetch frequently bought together items\nclient.recommendations({\n  configurationKey: 'config1',\n  itemId: '1065921'\n});\n```\n\n### Search analytics\n\n#### Send search event to analytics\n\nWhen search is executed, send the event to your AddSearch Analytics Dashboard.\n\n```js\n// If the numberOfResults is 0, the search is shown in the list of \"queries with no hits\"\nclient.sendStatsEvent('search', keyword, { numberOfResults: n });\n```\n\n#### Send click event to analytics\n\nWhen a search results is clicked, send the event to your AddSearch Analytics Dashboard. Click\ninformation is shown in your statistics and used by the self-learning search algorithm.\n\n```js\n// documentId is the 32-character long id that is part of each hit in search results.\n// position is the position of the document that was clicked, the first result being 1\nclient.sendStatsEvent('click', keyword, { documentId: id, position: n });\n```\n\n#### Set or get stats session ID\n\nControl the search session ID manually. Search queries with the same ID are grouped on the Analytics\nDashboard. For example, in a search-as-you-type implementation the final keyword of a given session\nis shown.\n\n```js\nclient.getStatsSessionId();\nclient.setStatsSessionId(id);\n```\n\n#### Collect search events automatically\n\nSend search events automatically to the Analytics Dashboard. Not recommended in search-as-you-type\nimplementations, as every keystroke would fire a statistics event\n\n```js\n// Control whether search queries are sent to your AddSearch Analytics Dashboard automatically or not (default: true)\nclient.setCollectAnalytics(false);\n```\n\n#### Set a tag for analytics events\n\nDefines a tag associated with all analytics events reported by the client. These tags will be\navailable as filters in the AddSearch Analytics Dashboard. You can use tags, for instance, in A/B\ntesting to compare which search UIs are most effective. Splitting the analytics with tags may also\nprovide insights to the behaviour of audiences on different websites.\n\n```js\n// Specify a tag for analytics events (the maximum length is 50 characters)\nclient.setAnalyticsTag('Navigation search');\n```\n\n### Personalization\n\n#### Enable personalization tracking\n\nEnable personalization tracking, user token will be included in every stat events as \"session ID\".\n\u003cbr/\u003e\n\nSet stats session ID if user token is generated by your site.\n\n```js\nclient.setStatsSessionId(userToken);\n```\n\nIf session is not set, a UUID is generated and stored in a cookie named 'addsearchUserToken`.\nSpecify the expiration date of the cookie. Default is 180.\n\n```js\n// Defaults - isEnabled: false, expirationDates: 180\nclient.enablePersonalizationTracking(isEnabled, expirationDates);\n```\n\n#### Allow storing AddSearch's user token in cookie\n\nBy default, the value is false. Set it to false when users reject cookie (AddSearch's cookie can be\ncategorized as functional/analytics cookie), or set to true when user accepts cookie.\n\n```js\n// Default: false\nclient.consentAddSearchCookie(true);\n```\n\n#### Set user token to search query (for personalized search results)\n\n```js\n// Add a user token to the search request (if personalization in use)\nclient.setUserToken(userToken);\n```\n\n#### Get user token from AddSearch cookie\n\nGet the user token which is stored in AddSearch cookie (if available).\n\n```js\n// Get a user token\nclient.getUserTokenInPersonalization();\n```\n\n#### Send personalization events with search query - deprecated\n\nIn personalized search, user events are typically sent to AddSearch via API and a user token is\npassed with the search query (see setUserToken function). An alternative way is to send user events\nneeded for personalization with the search query.\n\n```js\n// Events depend on the personalization strategy\n// Contact AddSearch for more information\nvar events = [\n  { favorite_genre: 'rock' },\n  { favorite_band: 'Red Hot Chili Peppers' },\n  { least_favorite_genre: 'country' }\n];\n\nclient.setPersonalizationEvents(events);\n```\n\n### Other\n\n#### Set JSON Web Token (for authentication)\n\n```js\n// Add JWT to the search request (if protected search index)\nclient.setJWT(token);\n```\n\n#### Set API throttling\n\n```js\n// Set Search API throttle time in milliseconds. Default is 200.\nclient.setThrottleTime(500);\n```\n\n#### Set API hostname\n\n`option` is an object with the following properties, all of which are optional. If `option` is not\ndefined, host name will be applied for all requests.\n\n- **searchApiRequestOnly**: If true, the new host name is only applied for searchApi requests\n  (default: false)\n- **statsApiRequestOnly**: If true, the new host name is only applied for statsApi requests\n  (default: false)\n\n```js\n// Set API hostname (e.g. for dedicated environments)\nclient.setApiHostname('api.addsearch.com', option);\n```\n\n#### Set API request interceptor\n\n`configurationObject` contains 2 keys: \u003cstring\u003e`url` and \u003cobject\u003e`headers`. Modify the\n`configurationObject` before it is sent.\n\n`option` is an object with the following properties, all of which are optional. If `option` is not\ndefined, the interceptor will be used for all requests.\n\n- **searchApiRequestOnly**: If true, the interceptor is only used for searchApi requests (default:\n  false)\n- **statsApiRequestOnly**: If true, the interceptor is only used for statsApi requests (default:\n  false)\n\n```js\nfunction callback(configurationObject) {\n  configurationObject.headers['X-Api-Key'] = 'YOUR API KEY';\n  return configurationObject;\n}\nclient.setApiRequestInterceptor(callback, option);\n```\n\n## AI Answers API\n\n#### Fetch AI answers\n\n```js\n// Get AI generated answer with a question\nclient.aiAnswers('A question to get AI generated answers', callback);\n```\n\nExample of callback function and how the response looks like:\n```js\ncallbackFn = function (response) {\n  \n  console.log(response);\n  \n  // response object contains the answer\n  // {\n  //   \"answer\": \"The answer to the question\",\n  //   \"conversation_id\": \"31f33b53-1fe1-4734-884f-fefa470f1389\",\n  //   \"ids\": \u003carray of ids belonging to source documents\u003e, for example ['073010f023db7c6d558123f73a9b4f82', '821f7bea12daf0eda17ba2755979f7a5'],\n  //   \"source_documents\": \u003cdocuments that provide context for AI generated answers, the object of this field looks similarly to the response of regular SearchApi result\u003e\n  // }\n};\n````\n\n#### Send Sentiment Analysis\n\n```js\n// possible sentiment_value: positive, negative\nclient.putSentimentClick('conversation_id', 'sentiment_value');\n```\n\n\n#### Set AI-answers filtering object\n\nSet complex filtering object that can contain nested _and_, _or_, _not_.\nKey filterable properties include: _category_, _custom_fields.\u003cyour_field_name\u003e_, _language_, _doc_date_\n\n```js\n// Find results where region is en-us, color is not white\nvar aiAnswersFilter = {\n  and: [\n    { 'custom_fields.region': 'en-us' },\n    { not: { 'custom_fields.color': 'white' } }\n  ]\n};\n\nclient.setAiAnswersFilterObject(aiAnswersFilter);\n```\n\n## POST API\n:exclamation: POST API is not fully supported. If you need to use some methods in the library, please contact our support.\n\n#### Fetch AI answers\n\n```js\n// default method: \"GET\"\nclient.setApiMethod('POST');\n```\n\n## Indexing API\n\nWith the Indexing API, you can fetch, create, update, and delete single documents or batches of\ndocuments.\n\nIndexing API functions are meant to be used with Node.js. Never expose secret key in your website\ncode.\n\n```js\n// Create client with your keys\nvar client = new AddSearchClient('YOUR PUBLIC SITEKEY', 'YOUR SECRET KEY');\n```\n\nThe secret key can be found from AddSearch Dashboard's \"Setup\" \u003e \"Keys and installation\" page.\nAlways keep the key secret.\n\nAll Indexing API functions are Promise-based.\n\n### Document structure\n\nDocuments can contain a set of pre-defined fields, as well as any number of custom fields defined\nunder the **custom_fields** key.\n\nUsing pre-defined fields is optional, but default\n[Search UI](https://github.com/AddSearch/search-ui) components display them by default, so\npre-defined field give you visible results a bit faster.\n\nPre-defined fields are: url, title, and main_content.\n\nExample document:\n\n```js\nconst doc = {\n  id: '1234',\n  url: 'https://www.example-store.com/product-x',\n  title: 'Example product',\n  main_content: 'Lorem ipsum',\n  custom_fields: {\n    name: 'Example product',\n    description: 'Description for the example product',\n    price_cents: 599,\n    average_customer_rating: 4.5,\n    release_date: 1589200255\n  }\n};\n```\n\nData types for custom fields are automatically detected from the content. Supported data types are:\n\n- text\n- integer\n- double\n\nDates should be defined as UNIX timestamps with integer values.\n\n### Document ID\n\nIf the **id** is not defined in the document at indexing time, it is generated automatically either\nrandomly or from the **url** field.\n\n```js\n// ID defined by the user\nconst docWithDefinedId = {\n  id: '1234',\n  custom_fields: {}\n};\n```\n\n```js\n// ID created from the URL field (md5 of the url)\nconst docWithURL = {\n  url: 'https://..',\n  custom_fields: {}\n};\n```\n\n```js\n// ID generated randomly\nconst docWithAutogeneratedId = {\n  // No id or url fields\n  custom_fields: {}\n};\n```\n\n### Save document\n\nAdd a document to the index, or update a document.\n\n```js\nconst doc = {\n  id: '1234',\n  custom_fields: {\n    name: 'Example product'\n  }\n};\n\n// Save document\nclient\n  .saveDocument(doc)\n  .then((response) =\u003e {\n    console.log(response);\n  })\n  .catch((error) =\u003e {\n    console.log(error);\n  });\n```\n\n### Get document by ID\n\nFetch a specific document by ID.\n\n```js\nclient\n  .getDocument(id)\n  .then((response) =\u003e {\n    console.log(response);\n  })\n  .catch((error) =\u003e {\n    console.log(error);\n  });\n```\n\n### Delete document by ID\n\nDelete a specific document by ID.\n\n```js\nclient\n  .deleteDocument(id)\n  .then((response) =\u003e {\n    console.log(response);\n  })\n  .catch((error) =\u003e {\n    console.log(error);\n  });\n```\n\n### Save batch of documents\n\nAdd or update bunch of documents defined in an array.\n\n```js\nconst batch = {\n  documents: [\n    {\n      id: '1234',\n      custom_fields: {\n        name: 'Product 1'\n      }\n    },\n    {\n      id: '5678',\n      custom_fields: {\n        name: 'Product 2'\n      }\n    }\n  ]\n};\n\n// Save batch of documents\nclient\n  .saveDocumentsBatch(batch)\n  .then((response) =\u003e {\n    console.log(response);\n  })\n  .catch((error) =\u003e {\n    console.log(error);\n  });\n```\n\n### Delete batch of documents\n\nDelete multiple documents with an array of document IDs.\n\n```js\n// Array of document IDs\nconst batch = {\n  documents: ['1234', '5678']\n};\n\n// Delete batch of documents\nclient\n  .deleteDocumentsBatch(batch)\n  .then((response) =\u003e {\n    console.log(response);\n  })\n  .catch((error) =\u003e {\n    console.log(error);\n  });\n```\n\n## Supported browsers\n\nThe client is tested on\n\n- Chrome\n- Firefox\n- Edge\n- Safari 6.1+\n- Internet Explorer 10+\n- Node.js\n\n## Development\n\nTo modify this client library, clone this repository to your computer and execute following\ncommands.\n\n#### Install dependencies\n\n```sh\nnpm install\n```\n\n#### Code\n\nRe-compile automatically when source files are changed\n\n```sh\nnpm run watch\n```\n\n#### Run tests\n\n```sh\nnpm test\n```\n\n#### Build\n\n```sh\nnpm run build\n```\n\nBuilt bundle is saved under the _dist/_ folder\n\n## Support\n\nFeel free to send any questions, ideas, and suggestions at\n[support@addsearch.com](mailto:support@addsearch.com) or visit\n[addsearch.com](https://www.addsearch.com/) for more information.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faddsearch%2Fjs-client-library","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faddsearch%2Fjs-client-library","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faddsearch%2Fjs-client-library/lists"}