API Documentation - v0.14.0

Version:

Introduction

Welcome to the Typesense API documentation. This documentation itself is open source. Please leave your feedback as issues on the GitHub repo or send us a pull-request to contribute edits.

To learn how to install and run Typesense, see our getting started guide instead.

API clients

At the moment, we have API clients for Javascript, Python, and Ruby.

We recommend that you use our API client library if it is available for your language.

gem install typesense
pip install typesense
// Node.js
npm install typesense

// Browser
<script src="dist/typesense.min.js"></script>

If you're using our Javascript client to access Typesense directly from the browser, be sure to start the Typesense server with the --enable-cors flag.

Authentication

require 'typesense'

client = Typesense::Client.new(
  nodes: [
    {
      host:     'localhost',
      port:     8108,
      protocol: 'http'
    }
  ],

  api_key:  '<API_KEY>',
  connection_timeout_seconds: 2
)
import typesense

client = typesense.Client({
  'nodes': [{
    'host': 'localhost',
    'port': '8108',
    'protocol': 'http',
  }],

  'api_key': '<API_KEY>',
  'connection_timeout_seconds': 2
})
/*
 *  Our Javascript client library works on both the client and the browser.
 *  When using the library on the browser, please be sure to use the
 *  search-only API Key rather than the master API key since the latter
 *  has write access to Typesense and you don't want to expose that.
 */
let client = new Typesense.Client({
  'nodes': [{
    'host': 'localhost',
    'port': '8108',
    'protocol': 'http',
  }],

  'apiKey': '<API_KEY>'
  'connectionTimeoutSeconds': 2
})
# API authentication is done via the `X-TYPESENSE-API-KEY` HTTP header.
curl -H "X-TYPESENSE-API-KEY: <API_KEY>" "http://localhost:8108/collections"

Usage

In Typesense, a group of related documents is called a collection. A collection is roughly equivalent to a table in a relational database.

Create a collection

When a collection is created, we give it a name and describe the fields that will be indexed from the documents that are added to the collection.

Your documents can contain other fields not mentioned in the collection's schema - they will be stored but not indexed.

schema = {
  'name'      => 'companies',
  'fields'    => [
    {
      'name'  => 'company_name',
      'type'  => 'string'
    },
    {
      'name'  => 'num_employees',
      'type'  => 'int32'
    },
    {
      'name'  => 'country',
      'type'  => 'string',
      'facet' => true
    }
  ],
  'default_sorting_field' => 'num_employees'
}

client.collections.create(schema)
schema = {
  'name': 'companies',
  'fields': [
    {
      'name'  :  'company_name',
      'type'  :  'string'
    },
    {
      'name'  :  'num_employees',
      'type'  :  'int32'
    },
    {
      'name'  :  'country',
      'type'  :  'string',
      'facet' :  True
    }
  ],
  'default_sorting_field': 'num_employees'
}

client.collections.create(schema)
let schema = {
  'name': 'companies',
  'num_documents': 0,
  'fields': [
    {
      'name': 'company_name',
      'type': 'string',
      'facet': false
    },
    {
      'name': 'num_employees',
      'type': 'int32',
      'facet': false
    },
    {
      'name': 'country',
      'type': 'string',
      'facet': true
    }
  ],
  'default_sorting_field': 'num_employees'
}

client.collections().create(schema)
curl "http://localhost:8108/collections" -X POST -H "Content-Type: application/json" \
       -H "X-TYPESENSE-API-KEY: ${TYPESENSE_API_KEY}" -d '{
         "name": "companies",
         "fields": [
           {"name": "company_name", "type": "string" },
           {"name": "num_employees", "type": "int32" },
           {"name": "country", "type": "string", "facet": true }
         ],
         "default_sorting_field": "num_employees"
       }'
Sample response
{
  "name": "companies",
  "num_documents": 0,
  "fields": [
    {"name": "company_name", "type": "string" },
    {"name": "num_employees", "type": "int32" },
    {"name": "country", "type": "string", "facet": true }
  ],
  "default_sorting_field": "num_employees"
}
Definition

POST ${TYPESENSE_HOST}/collections

Arguments
Parameter Required Description
name yes Name of the collection you wish to create.
fields yes

A list of fields that you wish to index for querying, filtering and faceting. For each field, you have to specify the name and type.

Declaring a field as optional

A field can be declared as optional by setting "optional": true.

Declaring a field as a facet

A field can be declared as a facetable field by setting "facet": true.

Faceted fields are indexed verbatim without any tokenization or preprocessing. For example, if you are building a product search, color and brand could be defined as facet fields.

default_sorting_field yes

The name of an int32 / float field that determines the order in which the search results are ranked when a sort_by clause is not provided during searching. This field must indicate some kind of popularity. For example, in a product search application, you could define num_reviews field as the default_sorting_field.

Additionally, when a word in a search query matches multiple possible words (either because of a typo or during a prefix search), this parameter is used to rank such equally matching tokens. For e.g. both "john" and "joan" are 1-typo away from "jofn". Similarly, in a prefix search, both "apple" and "apply" would match the prefix "app".

Supported search field types

Typesense allows you to index the following types of fields:

string
int32
int64
float
bool

You can define an array or multi-valued field by suffixing a [] at the end:

string[]
int32[]
int64[]
float[]
bool[]

Index a document

A document to be indexed in a given collection must conform to the schema of the collection.

If the document contains an `id` field of type `string`, Typesense would use that field as the identifier for the document. Otherwise, Typesense would assign an identifier of its choice to the document.

document = {
  'id'            => '124',
  'company_name'  => 'Stark Industries',
  'num_employees' => 5215,
  'country'       => 'USA'
}

client.collections['companies'].documents.create(document)
document = {
  'id': '124',
  'company_name': 'Stark Industries',
  'num_employees': 5215,
  'country': 'USA'
}

client.collections['companies'].documents.create(document)
let document = {
  'id': '124',
  'company_name': 'Stark Industries',
  'num_employees': 5215,
  'country': 'USA'
}

client.collections('companies').documents().create(document)
curl "http://localhost:8108/collections/companies/documents" -X POST \
        -H "Content-Type: application/json" \
        -H "X-TYPESENSE-API-KEY: ${TYPESENSE_API_KEY}" \
        -d '{
          "id": "124",
          "company_name": "Stark Industries",
          "num_employees": 5215,
          "country": "USA"
        }'
Sample Response
{
  "id": "124",
  "company_name": "Stark Industries",
  "num_employees": 5215,
  "country": "USA"
}
Definition

POST ${TYPESENSE_HOST}/collections/:collection/documents

Search a collection

In Typesense, a search consists of a query against one or more text fields and a list of filters against numerical or facet fields. You can also sort and facet your results.

search_parameters = {
  'q'         => 'stark',
  'query_by'  => 'company_name',
  'filter_by' => 'num_employees:>100',
  'sort_by'   => 'num_employees:desc'
}

client.collections['companies'].documents.search(search_parameters)
search_parameters = {
  'q'         : 'stark',
  'query_by'  : 'company_name',
  'filter_by' : 'num_employees:>100',
  'sort_by'   : 'num_employees:desc'
}

client.collections['companies'].documents.search(search_parameters)
let searchParameters = {
  'q'         : 'stark',
  'query_by'  : 'company_name',
  'filter_by' : 'num_employees:>100',
  'sort_by'   : 'num_employees:desc'
}

client.collections('companies').documents().search(searchParameters)
curl -H "X-TYPESENSE-API-KEY: ${TYPESENSE_API_KEY}" \
"http://localhost:8108/collections/companies/documents/search\
?q=stark&query_by=company_name&filter_by=num_employees:>100\
&sort_by=num_employees:desc"
Sample response
{
  "facet_counts": [],
  "found": 1,
  "took_ms": 1,
  "hits": [
    {
      "highlights": [
        {
          "field": "company_name",
          "snippet": "<mark>Stark</mark> Industries"
        }
      ],
      "document": {
        "id": "124",
        "company_name": "Stark Industries",
        "num_employees": 5215,
        "country": "USA"
      }
    }
  ]
}

When a string[] field is queried, the highlights structure would include the corresponding matching array indices of the snippets. For e.g:

{
      ...
      "highlights": [
        {
          "field": "addresses",
          "indices": [0,2],
          "snippets": [
            "10880 <mark>Malibu</mark> Point, <mark>Malibu,</mark> CA 90265",
            "10000 <mark>Malibu</mark> Point, <mark>Malibu,</mark> CA 90265"
          ]
        }
      ],
      ...
}
Group by

You can aggregate search results into groups or buckets by specify one or more group_by fields.

Grouping hits this way is useful in:

  • Deduplication: By using one or more group_by fields, you can consolidate items and remove duplicates in the search results. For example, if there are multiple shoes of the same size, by doing a group_by=size&group_limit=1, you ensure that only a single shoe of each size is returned in the search results.
  • Correcting skew: When your results are dominated by documents of a particular type, you can use group_by and group_limit to correct that skew. For example, if your search results for a query contains way too many documents of the same brand, you can do a group_by=brand&group_limit=3 to ensure that only the top 3 results of each brand is returned in the search results.

NOTE: To group on a particular field, it must be a faceted field.

Grouping returns the hits in a nested structure, that's different from the plain JSON response format we saw earlier. Let's repeat the query we made earlier with a group_by parameter:

search_parameters = {
  'q'           => 'stark',
  'query_by'    => 'company_name',
  'filter_by'   => 'num_employees:>100',
  'sort_by'     => 'num_employees:desc'
  'group_by'    => 'country'
  'group_limit' => '1'
}

client.collections['companies'].documents.search(search_parameters)
search_parameters = {
  'q'           : 'stark',
  'query_by'    : 'company_name',
  'filter_by'   : 'num_employees:>100',
  'sort_by'     : 'num_employees:desc'
  'group_by'    : 'country'
  'group_limit' : '1'
}

client.collections['companies'].documents.search(search_parameters)
let searchParameters = {
  'q'            : 'stark',
  'query_by'     : 'company_name',
  'filter_by'    : 'num_employees:>100',
  'sort_by'      : 'num_employees:desc'
  'group_by'     : 'country'
  'group_limit'  : '1'
}

client.collections('companies').documents().search(searchParameters)
curl -H "X-TYPESENSE-API-KEY: ${TYPESENSE_API_KEY}" \
"http://localhost:8108/collections/companies/documents/search\
?q=stark&query_by=company_name&filter_by=num_employees:>100\
&sort_by=num_employees:desc&group_by=country&group_limit=1"
{
  "facet_counts": [],
  "found": 1,
  "took_ms": 1,
  "grouped_hits": [
    {
      "group_key": ["USA"],
      "hits": [
        {
          "highlights": [
            {
              "field": "company_name",
              "snippet": "<mark>Stark</mark> Industries"
            }
          ],
          "document": {
            "id": "124",
            "company_name": "Stark Industries",
            "num_employees": 5215,
            "country": "USA"
          }
        }
      ]
    }
  ]
}
Definition

GET ${TYPESENSE_HOST}/collections/:collection/documents/search

Arguments
Parameter Required Description
q yes

The query text to search for in the collection.

Use * as the search string to return all documents. This is typically useful when used in conjunction with filter_by.

For example, to return all documents that match a filter, use:
q=*&filter_by=num_employees:10

query_by yes

One or more string / string[] fields that should be queried against. Separate multiple fields with a comma: company_name, country

The order of the fields is important: a record that matches on a field earlier in the list is considered more relevant than a record matched on a field later in the list. So, in the example above, documents that match on the company_name field are ranked above documents matched on the country field.

max_hits no

Maximum number of hits returned. Increasing this value might increase search latency.

Use all to return all hits found.

Default: 500

prefix no

Boolean field to indicate that the last word in the query should be treated as a prefix, and not as a whole word. This is necessary for building autocomplete and instant search interfaces.

Default: true

filter_by no

Filter conditions for refining your search results.

A field can be matched against one or more values.

country: USA
country: [USA, UK]

Separate multiple conditions with the && operator.

num_employees:>100 && country: [USA, UK]

More examples:

num_employees:10
num_employees:<=10

sort_by no

A list of numerical fields and their corresponding sort orders that will be used for ordering your results. Separate multiple fields with a comma. Upto 3 sort fields can be specified.

E.g. num_employees:desc,year_started:asc

The text similarity score is exposed as a special _match_score field that you can use in the list of sorting fields.

If one or two sorting fields are specified, _match_score is used for tie breaking, as the last sorting field.

Default:

If no sort_by parameter is specified, results are sorted by: _match_score:desc,default_sorting_field:desc.

facet_by no

A list of fields that will be used for faceting your results on. Separate multiple fields with a comma.

max_facet_values no

Maximum number of facet values to be returned.

facet_query no

Facet values that are returned can now be filtered via this parameter. The matching facet text is also highlighted. For example, when faceting by category, you can set facet_query=category:shoe to return only facet values that contain the prefix "shoe".

num_typos no

Number of typographical errors (1 or 2) that would be tolerated.

Damerau–Levenshtein distance is used to calculate the number of errors.

Default: 2

page no

Results from this specific page number would be fetched.

per_page no

Number of results to fetch per page.

Default: 10

group_by no

You can aggregate search results into groups or buckets by specify one or more group_by fields. Separate multiple fields with a comma.

NOTE: To group on a particular field, it must be a faceted field.

E.g. group_by=country,company_name

group_limit no

Maximum number of hits to be returned for every group. If the group_limit is set as K then only the top K hits in each group are returned in the response.

Default: 3

include_fields no

Comma-separated list of fields from the document to include in the search result.

exclude_fields no

Comma-separated list of fields from the document to exclude in the search result.

highlight_full_fields no

Comma separated list of fields which should be highlighted fully without snippeting.

Default: all fields will be snippeted.

snippet_threshold no

Field values under this length will be fully highlighted, instead of showing a snippet of relevant portion.

Default: 30

drop_tokens_threshold no

If the number of results found for a specific query is less than this number, Typesense will attempt to drop the tokens in the query until enough results are found. Tokens that have the least individual hits are dropped first. Set drop_tokens_threshold to 0 to disable dropping of tokens.

Default: 10

typo_tokens_threshold no

If the number of results found for a specific query is less than this number, Typesense will attempt to look for tokens with more typos until enough results are found.

Default: 100

pinned_hits no

A list of records to unconditionally include in the search results at specific positions.

An example use case would be to feature or promote certain items on the top of search results.

A comma separated list of record_id:hit_position. Eg: to include a record with ID 123 at Position 1 and another record with ID 456 at Position 5, you'd specify 123:1,456:5.

You could also use the Overrides feature to override search results based on rules. Overrides are applied first, followed by pinned_hits and finally hidden_hits.

hidden_hits no

A list of records to unconditionally hide from search results.

A comma separated list of record_ids to hide. Eg: to hide records with IDs 123 and 456, you'd specify 123,456.

You could also use the Overrides feature to override search results based on rules. Overrides are applied first, followed by pinned_hits and finally hidden_hits.

Retrieve a document

Fetch an individual document from a collection by using its id.
client.collections['companies'].documents['124'].retrieve
client.collections['companies'].documents['124'].retrieve()
client.collections('companies').documents('124').retrieve()
$ curl -H "X-TYPESENSE-API-KEY: ${TYPESENSE_API_KEY}" -X GET \
      "http://localhost:8108/collections/companies/documents/124"
Sample response
{
  "id": "124",
  "company_name": "Stark Industries",
  "num_employees": 5215,
  "country": "USA"
}
Definition

GET ${TYPESENSE_HOST}/collections/:collection/documents/:id

Delete a document

Delete an individual document from a collection by using its id.

client.collections['companies'].documents['124'].delete
client.collections['companies'].documents('124').delete()
client.collections('companies').documents('124').delete()
curl -H "X-TYPESENSE-API-KEY: ${TYPESENSE_API_KEY}" -X DELETE \
    "http://localhost:8108/collections/companies/documents/124"
Sample response
{
  "id": "124",
  "company_name": "Stark Industries",
  "num_employees": 5215,
  "country": "USA"
}
Definition

DELETE ${TYPESENSE_HOST}/collections/:collection/documents/:id

Retrieve a collection

Retrieve the details of a collection, given its name.

client.collections['companies'].retrieve
client.collections['companies'].retrieve()
client.collections('companies').retrieve()
curl -H "X-TYPESENSE-API-KEY: ${TYPESENSE_API_KEY}" -X GET
    "http://localhost:8108/collections/companies"
Sample response
{
  "name": "companies",
  "num_documents": 1250,
  "fields": [
    {"name": "company_name", "type": "string"},
    {"name": "num_employees", "type": "int32"},
    {"name": "country", "type": "string", "facet": true}
  ],
  "default_sorting_field": "num_employees"
}
Definition

GET ${TYPESENSE_HOST}/collections/:collection

Export documents from a collection

client.collections['companies'].documents.export
client.collections['companies'].documents.export()
client.collections('companies').documents().export()
curl -H "X-TYPESENSE-API-KEY: ${TYPESENSE_API_KEY}" -X GET
    "http://localhost:8108/collections/companies/documents/export"
Sample response
[
"{\"id\": \"124\", \"company_name\": \"Stark Industries\", \"num_employees\": 5215, \
\"country\": \"US\"}",
"{\"id\": \"125\", \"company_name\": \"Future Technology\", \"num_employees\": 1232, \
\"country\": \"UK\"}",
"{\"id\": \"126\", \"company_name\": \"Random Corp.\", \"num_employees\": 531, \
\"country\": \"AU\"}"
]
[u'{"company_name":"Stark Industries","country":"USA","id":"124","num_employees":5215}',\
u'{"company_name":"Future Technology","country":"UK","id":"125","num_employees":1232}',\
u'{"company_name":"Random Corp.","country":"AU","id":"126","num_employees":531}']
['{"company_name":"Stark Industries","country":"USA","id":"124","num_employees":5215}',\
'{"company_name":"Future Technology","country":"UK","id":"125","num_employees":1232}',\
'{"company_name":"Random Corp.","country":"AU","id":"126","num_employees":531}']
{"id": "124", "company_name": "Stark Industries", "num_employees": 5215,\
"country": "US"}
{"id": "125", "company_name": "Future Technology", "num_employees": 1232,\
"country": "UK"}
{"id": "126", "company_name": "Random Corp.", "num_employees": 531,\
"country": "AU"}
Definition

GET ${TYPESENSE_HOST}/collections/:collection/documents/export

Import documents into a collection

The documents to be imported must be formatted in a newline delimited JSON stucture. You can feed the output file from a Typesense export operation directly as import.

Here's an example file:

{"name": "Stark Industries", "num_employees": 5215, "country": "USA"}
{"name": "Orbit Inc.", "num_employees": 256, "country": "UK"}

You can import the above documents.jsonl file like this.

curl -H "X-TYPESENSE-API-KEY: ${TYPESENSE_API_KEY}" -X POST --data-binary @documents.jsonl
"http://localhost:8108/collections/companies/documents/import"
Sample response
{
  "items":[
    { "success":true },
    { "success":true },
    { "success":true }
  ],
  "num_imported":3,
  "success":true
}

The response will consist of an items array that indicates the result of each document present in the request to be imported (in the same order). If the import of a single document fails, it does not affect the remaining documents.

If there is a failure, the response item will include a corresponding error message. For example, the second document had an import failure in the following response:

{
  "items":[
    { "success":true },
    { "success":false, "error": "Bad JSON." },
    { "success":true }
  ],
  "num_imported":2,
  "success":false
}

Note: we recommend importing documents 1MB at a time, to keep import speeds fast.

Definition

POST ${TYPESENSE_HOST}/collections/:collection/documents/import

List all collections

Returns a summary of all your collections. The collections are returned sorted by creation date, with the most recent collections appearing first.

client.collections.retrieve
client.collections.retrieve()
client.collections().retrieve()
curl -H "X-TYPESENSE-API-KEY: ${TYPESENSE_API_KEY}" "http://localhost:8108/collections"
Sample response
{
  "collections": [
    {
      "num_documents": 1250,
      "name": "companies",
      "fields": [
        {"name": "company_name", "type": "string"},
        {"name": "num_employees", "type": "int32"},
        {"name": "country", "type": "string", "facet": true}
      ],
      "default_sorting_field": "num_employees"
    },
    {
      "num_documents": 1250,
      "name": "ceos",
      "fields": [
        {"name": "company_name", "type": "string"},
        {"name": "full_name", "type": "string"},
        {"name": "from_year", "type": "int32"}
      ],
      "default_sorting_field": "num_employees"
    }
  ]
}
Definition

GET ${TYPESENSE_HOST}/collections

Drop a collection

Permanently drops a collection. This action cannot be undone. For large collections, this might have an impact on read latencies.

client.collections['companies'].delete
client.collections['companies'].delete()
client.collections('companies').delete()
curl -H "X-TYPESENSE-API-KEY: ${TYPESENSE_API_KEY}" -X DELETE
    "http://localhost:8108/collections/companies"
Sample response
{
  "name": "companies",
  "num_documents": 1250,
  "fields": [
    {"name": "company_name", "type": "string"},
    {"name": "num_employees", "type": "int32"},
    {"name": "country", "type": "string", "facet": true}
  ],
  "default_sorting_field": "num_employees"
}
Definition

DELETE ${TYPESENSE_HOST}/collections/:collection

API Keys

Typesense allows you to create API Keys with fine-grain access control. You can restrict access on both a per-collection and per-action level.

We will be using the initial bootstrap key that you started Typesense with (via --api-key>) to create additional keys. It's strongly recommended that you don't use the bootstrap API key directly in your production applications. Instead you want to generate an appropriately-scoped key for the application at hand.

Create an API Key

Let's begin by creating an API key that allows you to do all operations, i.e. it's effectively an admin key and is equivalent to the key that you start Typesense with (via --api-key).

key = client.keys.create({
  'description' => 'Admin key.',
  'actions' => ['*'],
  'collections' => ['*']
})
key = client.keys.create({
  "description": "Admin key.",
  "actions": ["*"],
  "collections": ["*"]
})
key = client.keys().create({
  'description': 'Admin key.',
  'actions': ['*'],
  'collections': ['*']
})
curl 'http://localhost:8108/keys' -X POST -H "X-TYPESENSE-API-KEY: ${TYPESENSE_API_KEY}" \
-H 'Content-Type: application/json' \
-d '{"description":"Admin key.","actions": ["*"], "collections": ["*"]}'

By setting both actions and collections to a wildcard ['*'] scope, we're able to create an admin key that gives you universal access. However, you should refrain from creating such widely scoped keys.

NOTE: The generated key is returned only during creation. You want to store this key carefully in a secure place.

Let's now see how we can create a search-only key that allows you to limit the key's scope to only the search action, and also for only a specific collection.

client.keys.create({
  'description' => 'Search-only companies key.',
  'actions' => ['documents:search'],
  'collections' => ['companies']
})
client.keys.create({
  "description": "Search-only companies key.",
  "actions": ["documents:search"],
  "collections": ["companies"]
})
client.keys().create({
  'description': 'Admin key.',
  'actions': ['documents:search'],
  'collections': ['companies']
})
curl 'http://localhost:8108/keys' -X POST -H "X-TYPESENSE-API-KEY: ${TYPESENSE_API_KEY}" \
-H 'Content-Type: application/json' \
-d '{"description":"Search-only companies key.","actions": ["documents:search"], "collections": ["companies"]}'

By setting the actions scope to ["documents:search"] and the collections scope to ["companies"], we can generate a key that is allowed to only conduct searches on the companies collection.

Sample response
{
  "actions": [
    "*"
  ],
  "collections": [
    "*"
  ],
  "description": "Admin key.",
  "id": 1,
  "value": "k8pX5hD0793d8YQC5aD1aEPd7VleSuGP"
}
Definition

POST ${TYPESENSE_HOST}/keys

Sample actions
Action Description
documents:search

Allows only search requests.

documents:get

Allows fetching a single document.

collections:delete

Allows a collection to be deleted.

collections:create

Allows a collection to be created.

collections:*

Allow all kinds of collection related operations.

*

Allows all operations.

Retrieve an API Key

Retrieve (metadata about) a key.

key = client.keys[1].retrieve
key = client.keys[1].retrieve()
key = client.keys(1).retrieve()
curl 'http://localhost:8108/keys/1' -X GET -H "X-TYPESENSE-API-KEY: ${TYPESENSE_API_KEY}"
Sample response
{
  "actions": [ "documents:search" ],
  "collections": [ "*" ],
  "description": "Search-only key.",
  "id": 1,
  "value_prefix": "vxpx"
}

Notice how only the key prefix is returned when you retrieve a key. Due to security reasons, only the create endpoint returns the full API key.

Definition

GET ${TYPESENSE_HOST}/keys/:id

List all keys

Retrieve (metadata about) all keys.

client.keys.retrieve
client.keys.retrieve()
client.keys().retrieve()
curl 'http://localhost:8108/keys' -X GET -H "X-TYPESENSE-API-KEY: ${TYPESENSE_API_KEY}"
Sample response
{
  "keys": [
    {
      "actions": [
        "documents:search"
      ],
      "collections": [
        "users"
      ],
      "description": "Search-only key.",
      "id": 1,
      "value_prefix": "iKBT"
    },
    {
      "actions": [
        "documents:search"
      ],
      "collections": [
        "users"
      ],
      "description": "Search-only key.",
      "id": 2,
      "value_prefix": "wst8"
    }
  ]
}

Notice how only the key prefix is returned when you retrieve a key. Due to security reasons, only the create endpoint returns the full API key.

Definition

GET ${TYPESENSE_HOST}/keys

Delete API Key

Delete an API key given its ID.

key = client.keys[1].delete
key = client.keys[1].delete()
key = client.keys(1).delete()
curl 'http://localhost:8108/keys/1' -X DELETE -H "X-TYPESENSE-API-KEY: ${TYPESENSE_API_KEY}"
Sample response
{
  "id": 1
}
Definition

DELETE ${TYPESENSE_HOST}/keys/:id

Generate Scoped Search Key

You can generate scoped search API keys that have embedded search parameters in them. This is useful for example when you have multi-tenant data indexed in your Typesense instance, but only want your users to access their own subset of the data.

To do this, you can embed a filter in a generated scoped search API key. When you use that key for search operations, those filters will get automatically applied and cannot be overriden.

We can generate scoped search API keys without having to make any calls to the Typesense server. We use an API key that we previously generated with a search scope, create an HMAC digest of the parameters with this key and use that as the API key. Our client libraries handle this logic for you, but you can also generate scoped search API keys from the command line.

Note: Remember to never expose your main search key client-side, since exposing the main search key will allow anyone to query the entire data set without your embedded search parameters.

key_with_search_permissions = 'RN23GFr1s6jQ9kgSNg2O7fYcAUXU7127'
client.keys().generate_scoped_search_key(key_with_search_permissions, {'filter_by': 'company_id:124'})
key_with_search_permissions = 'RN23GFr1s6jQ9kgSNg2O7fYcAUXU7127'
client.keys().generate_scoped_search_key(key_with_search_permissions, {"filter_by": "company_id:124"})
keyWithSearchPermissions = 'RN23GFr1s6jQ9kgSNg2O7fYcAUXU7127'
client.keys().generateScopedSearchKey(keyWithSearchPermissions, {'filter_by': 'company_id:124'})
KEY_WITH_SEARCH_PERMISSIONS="RN23GFr1s6jQ9kgSNg2O7fYcAUXU7127"
EMBEDDED_SEARCH_PARAMETERS_JSON='{"filter_by":"company_id:124"}'

digest=$(echo -n $EMBEDDED_SEARCH_PARAMETERS_JSON | openssl dgst -sha256 -hmac $KEY_WITH_SEARCH_PERMISSIONS -binary | base64)

scoped_api_key=$(echo -n "${digest}${KEY_WITH_SEARCH_PERMISSIONS:0:4}${EMBEDDED_SEARCH_PARAMETERS_JSON}" | base64)

echo $scoped_api_key
Sample response
"SC9sT0hncHFwTHNFc3U3d3psRDZBUGNXQUViQUdDNmRHSmJFQnNnczJ4VT1STjIzeyJmaWx0ZXJfYnkiOiJjb21wYW55X2lkOjEyNCJ9"

Curation

While Typesense makes it really easy and intuitive to deliver great search results, sometimes you might want to promote certain documents over others. Or, you might want to exclude certain documents from a query's result set.

Using overrides, you can include or exclude specific documents for a given query.

Create or update an override

In the following example, we are overriding the search results by placing the documents with ids 422 and 54 in the first and second positions respectively via the includes condition. Additionally, we're ensuring that the document with id 287 is not returned at all via the excludes condition. You need to specify only one of exclude or include.

Note how we are applying these overrides to an exact match of the query apple. Instead, if we want to match all queries that contained the word apple, we will use the contains match instead.

override = {
  "rule" => {
    "query" => "apple",
    "match" => "exact"
  },
  "includes" => [
    {"id" => "422", "position" => 1},
    {"id" => "54", "position" => 2}
  ],
  "excludes" => [
    {"id" => "287"}
  ]
}

# Creates/updates an override called `customize-apple` in the `companies` collection
client.collections['companies'].overrides.upsert('customize-apple', override)
override = {
  "rule": {
    "query": "apple",
    "match": "exact"
  },
  "includes": [
    {"id": "422", "position": 1},
    {"id": "54", "position": 2}
  ],
  "excludes": [
    {"id": "287"}
  ]
}

# Creates/updates an override called `customize-apple` in the `companies` collection
client.collections['companies'].overrides.upsert('customize-apple', override)
override = {
  "rule": {
    "query": "apple",
    "match": "exact"
  },
  "includes": [
    {"id": "422", "position": 1},
    {"id": "54", "position": 2}
  ],
  "excludes": [
    {"id": "287"}
  ]
}

// Creates/updates an override called `customize-apple` in the `companies` collection
client.collections('companies').overrides().upsert('customize-apple', override)
curl "http://localhost:8108/collections/companies/overrides/customize-apple" -X PUT \
-H "Content-Type: application/json" \
-H "X-TYPESENSE-API-KEY: ${TYPESENSE_API_KEY}" -d '{
  "rule": {
    "query": "apple",
    "match": "exact"
  },
  "includes": [
    {"id": "422", "position": 1},
    {"id": "54", "position": 2}
  ],
  "excludes": [
    {"id": "287"}
  ]
}'
Sample response
{
  "id": "customize-apple",
  "excludes": [
    {
      "id": "287"
    }
  ],
  "includes": [
    {
      "id": "422",
      "position": 1
    },
    {
      "id": "54",
      "position": 2
    }
  ],
  "rule": {
    "match": "exact",
    "query": "apple"
  }
}
Definition

PUT ${TYPESENSE_HOST}/collections/:collection/overrides/:id

Arguments
Parameter Required Description
excludes no List of document ids that should be excluded from the search results.
includes no List of document ids that should be included in the search results with their corresponding positions.
rule.query yes Indicates what search queries should be overridden.
rule.match yes Indicates whether the match on the query term should be exact or contains.

List all overrides

Listing all overrides associated with a given collection.

client.collections['companies'].overrides.retrieve
client.collections['companies'].overrides.retrieve()
client.collections('companies').overrides().retrieve
curl -H "X-TYPESENSE-API-KEY: ${TYPESENSE_API_KEY}" \
"http://localhost:8108/collections/companies/overrides"
Sample response
{
  "overrides":[
    {
      "id":"customize-apple",
      "excludes":[
        {
          "id":"287"
        }
      ],
      "includes":[
        {
          "id":"422",
          "position":1
        },
        {
          "id":"54",
          "position":2
        }
      ],
      "rule":{
        "match":"exact",
        "query":"apple"
      }
    }
  ]
}
Definition

GET ${TYPESENSE_HOST}/collections/:collection/overrides


Delete an override

Deleting an override associated with a collection.

client.collections['companies'].overrides['customize-apple'].delete
client.collections['companies'].overrides['customize-apple'].delete()
client.collections('companies').overrides('customize-apple').delete()
curl "http://localhost:8108/collections/companies/overrides/customize-apple" -X DELETE \
-H "X-TYPESENSE-API-KEY: ${TYPESENSE_API_KEY}"
Sample response
{
  "id": "customize-apple"
}
Definition

DELETE ${TYPESENSE_HOST}/collections/:collection/overrides/:id


Collection Alias

An alias is a virtual collection name that points to a real collection. If you're familiar with symbolic links on Linux, it's very similar to that.

Aliases are useful when you want to reindex your data in the background on a new collection and switch your application to it without any changes to your code. Let's take an example.

Let's say we have a collection called companies_june10 and an alias called companies pointing to that collection.

collection ---> companies_june10

On the next day (June 11), we will create a new collection called companies_june11 and start indexing the documents in the background into this collection. When we are done indexing, if we updated the companies alias to point to this new collection, your application would immediately start querying against the freshly indexed collection.

collection ---> companies_june11

Convenient isn't it? Let's now look at how we can create, update and manage aliases.


Create or Update an alias

aliased_collection = {
  'collection_name' => 'companies_june11'
}

# Creates/updates an alias called `companies` to the `companies_june11` collection
client.aliases.upsert('companies', aliased_collection)
aliased_collection = {
  'collection_name': 'companies_june11'
}

# Creates/updates an alias called `companies` to the `companies_june11` collection
client.aliases.upsert('companies', aliased_collection)
aliased_collection = {
  'collection_name': 'companies_june11'
}

// Creates/updates an alias called `companies` to the `companies_june11` collection
client.aliases().upsert('companies', aliased_collection)
curl "http://localhost:8108/aliases/companies" -X PUT \
    -H "Content-Type: application/json" \
    -H "X-TYPESENSE-API-KEY: ${TYPESENSE_API_KEY}" -d '{
        "collection_name": "companies_june11"
    }'
Sample response
{
  "name": "companies",
  "collection_name": "companies_june11",
}
Definition

PUT ${TYPESENSE_HOST}/aliases/:alias

Arguments
Parameter Required Description
collection_name yes Name of the collection you wish to map the alias to.

Retrieve an alias

We can find out which collection an alias points to by fetching it.

client.aliases['companies'].retrieve
client.aliases['companies'].retrieve()
client.aliases('companies').retrieve()
curl -H "X-TYPESENSE-API-KEY: ${TYPESENSE_API_KEY}" \
    "http://localhost:8108/aliases/companies"
Sample response
{
  "name": "companies",
  "collection_name": "companies_june11",
}
Definition

GET ${TYPESENSE_HOST}/aliases/:alias


List all aliases

List all aliases and the corresponding collections that they map to.

client.aliases.retrieve
client.aliases.retrieve()
client.aliases().retrieve()
curl -H "X-TYPESENSE-API-KEY: ${TYPESENSE_API_KEY}" \
     "http://localhost:8108/aliases"
Sample response
{
  "aliases": [
    {
      "name": "companies",
      "collection_name": "companies_june11"
    },
    {
      "name": "employees",
      "collection_name": "employees_june11"
    }
  ]
}
Definition

GET ${TYPESENSE_HOST}/aliases


Delete an alias

client.aliases['companies'].delete
client.aliases['companies'].delete()
client.aliases('companies').delete()
curl "http://localhost:8108/aliases/companies" -X DELETE
    -H "X-TYPESENSE-API-KEY: ${TYPESENSE_API_KEY}"
Sample response
{
  "name": "companies",
  "collection_name": "companies_june11"
}
Definition

DELETE ${TYPESENSE_HOST}/aliases/:alias

What's new in 0.14.0

In this release, we announce support for grouping documents on one or more fields. There are also a number of bug fixes.

  • [Feature] Group by: documents can now be grouped on one or more fields. You can also limit each group to the top K hits within the documents matching that group.
  • [Bug fix] Fixed an edge case in filtering of documents by int64 field.
  • [Bug fix] Allow float array field to accept integer values (i.e. whole numbers).
  • [Bug fix] Deletion of records with optional fields.
  • [Bug fix] Collection schema API response should contain the optional attribute of fields in the schema.

API errors

Typesense API uses standard HTTP response codes to indicate the success or failure of a request.

Codes in the 2xx range indicate success, codes in the 4xx range indicate an error given the information provided (e.g. a required parameter was omitted), and codes in the 5xx range indicate an error with the Typesense service itself.

Error Code Meaning
400 Bad Request - The request could not be understood due to malformed syntax.
401 Unauthorized - Your API key is wrong.
404 Not Found - The requested resource is not found.
409 Conflict - When a resource already exists.
422 Unprocessable Entity - Request is well-formed, but cannot be processed.
503 Service Unavailable - We’re temporarily offline. Please try again later.