Server Routes
The module automatically registers server API routes that proxy requests to your Typesense instance. These routes are available in both SSR and client-side contexts.
Security Note
Server routes use the API key configured in your nuxt.config.ts server runtime config, keeping your credentials secure. Never expose your admin API key to the client.
OpenAPI description
With openAPI: true the module also serves GET /api/typesense/openapi.json, an OpenAPI 3.1 document of every route on this page that is registered. See Module Options.
Error responses
Errors from Typesense are passed through with their original status code and message, so clients can handle them normally:
| Situation | Status | Message |
|---|---|---|
| Typesense returns an error (not found, invalid schema, bad key, ...) | Typesense's status | Typesense's own message |
| Typesense is unreachable | 502 | Typesense server is unreachable |
| Required parameter missing from the request | 400 | Describes the missing parameter |
| Anything unexpected | 500 | The error message |
try {
await $fetch('/api/typesense/collections/missing')
}
catch (error) {
// error.statusCode === 404, error.data.message === 'No collection with name `missing` found.'
}Status & Health
GET /api/typesense/status
Get the status and health information of your Typesense server.
Response:
{
name: 'TYPESENSE',
url: string,
version: string,
healthy: boolean
}Example:
// In a component or page
const { data: status } = await useFetch('/api/typesense/status')
console.log(status.value) // { name: 'TYPESENSE', url: '...', version: '...' }Collections
GET /api/typesense/collections
Retrieve all collections from your Typesense instance.
Response: Array of collection schemas
Example:
const { data: collections } = await useFetch('/api/typesense/collections')POST /api/typesense/collections
Create a new collection.
Request Body:
{
name: string
fields: Array<{
name: string
type: string
facet?: boolean
optional?: boolean
index?: boolean
}>
default_sorting_field?: string
}Example:
const { data: collection } = await useFetch('/api/typesense/collections', {
method: 'POST',
body: {
name: 'products',
fields: [
{ name: 'id', type: 'string' },
{ name: 'name', type: 'string' },
{ name: 'price', type: 'float' },
{ name: 'category', type: 'string', facet: true }
],
default_sorting_field: 'price'
}
})GET /api/typesense/collections/:name
Get details of a specific collection.
Parameters:
name- Collection name
Example:
const { data: collection } = await useFetch('/api/typesense/collections/products')PATCH /api/typesense/collections/:name
Update a collection's schema.
Parameters:
name- Collection name
Request Body: Collection schema updates
Example:
const { data } = await useFetch('/api/typesense/collections/products', {
method: 'PATCH',
body: {
fields: [
{ name: 'rating', type: 'float', drop: false }
]
}
})DELETE /api/typesense/collections/:name
Delete a collection and all its documents.
Parameters:
name- Collection name
Example:
await $fetch('/api/typesense/collections/old_products', {
method: 'DELETE'
})Collection Aliases
Collection aliases allow you to reference a collection by an alternative name, making it easier to switch between collections without changing your application code.
GET /api/typesense/alias
List all collection aliases.
const { aliases } = await $fetch('/api/typesense/alias')GET /api/typesense/alias/:alias
Get the collection associated with an alias.
Parameters:
alias- Alias name
Example:
const { data: aliasInfo } = await useFetch('/api/typesense/alias/current_products')PUT /api/typesense/alias/:alias
Create or update an alias to point to a collection.
Parameters:
alias- Alias name
Request Body:
{
collection_name: string
}Example:
await $fetch('/api/typesense/alias/current_products', {
method: 'PUT',
body: {
collection_name: 'products_v2'
}
})DELETE /api/typesense/alias/:alias
Delete an alias.
Parameters:
alias- Alias name
Example:
await $fetch('/api/typesense/alias/old_alias', {
method: 'DELETE'
})Documents
POST /api/typesense/documents/:collection
Create or index a single document in a collection.
Parameters:
collection- Collection name
Request Body: Document object matching the collection schema
Example:
const { data: document } = await useFetch('/api/typesense/documents/products', {
method: 'POST',
body: {
id: '1',
name: 'Laptop',
price: 999.99,
category: 'Electronics'
}
})POST /api/typesense/documents/:collection/search
Search for documents in a collection.
Parameters:
collection- Collection name
Request Body: Search parameters
{
q: string // Query text
query_by: string // Fields to query against
filter_by?: string // Filter conditions
sort_by?: string // Sort order
facet_by?: string // Fields to facet
max_facet_values?: number
per_page?: number // Results per page (default: 10)
page?: number // Page number (default: 1)
// ... and many more search parameters
}Example:
const { data: results } = await useFetch('/api/typesense/documents/products/search', {
method: 'POST',
body: {
q: 'laptop',
query_by: 'name,description',
filter_by: 'price:<1000',
sort_by: 'price:asc',
per_page: 20
}
})POST /api/typesense/documents/:collection/multi-search
Perform multiple searches in a single HTTP request for better performance.
Parameters:
collection- Collection name
Request Body:
{
searches: Array<{
q: string
query_by: string
// ... other search parameters
}>
}Example:
const { data: results } = await useFetch('/api/typesense/documents/products/multi-search', {
method: 'POST',
body: {
searches: [
{ q: 'laptop', query_by: 'name' },
{ q: 'phone', query_by: 'name' }
]
}
})GET /api/typesense/documents/:collection/export
Export all documents from a collection as JSONL.
Parameters:
collection- Collection name
Example:
const { data: documents } = await useFetch('/api/typesense/documents/products/export')POST /api/typesense/documents/:collection/import
Import multiple documents at once using JSONL format.
Parameters:
collection- Collection name
Request Body:
{
documents: string // JSONL string (one JSON object per line)
parameters?: {
action?: 'create' | 'update' | 'upsert' | 'emplace'
batch_size?: number
dirty_values?: 'coerce_or_reject' | 'coerce_or_drop' | 'drop' | 'reject'
}
}Example:
const documentsJsonl = `{"id":"1","name":"Product 1","price":10}
{"id":"2","name":"Product 2","price":20}`
const { data: result } = await useFetch('/api/typesense/documents/products/import', {
method: 'POST',
body: {
documents: documentsJsonl,
parameters: {
action: 'upsert',
batch_size: 100
}
}
})POST /api/typesense/documents/:collection/delete
Delete documents matching a filter query.
Parameters:
collection- Collection name
Request Body:
{
filter_by: string // Filter expression
}Example:
await $fetch('/api/typesense/documents/products/delete', {
method: 'POST',
body: {
filter_by: 'price:>1000'
}
})POST /api/typesense/documents/:collection/update
Update documents matching a filter query.
Parameters:
collection- Collection name
Request Body:
{
filter_by: string // Filter expression
updates: object // Fields to update
}Example:
await $fetch('/api/typesense/documents/products/update', {
method: 'POST',
body: {
filter_by: 'category:=Electronics',
updates: {
discount: 10
}
}
})GET /api/typesense/documents/:collection/id/:id
Retrieve a specific document by its ID.
Parameters:
collection- Collection nameid- Document ID
Example:
const { data: document } = await useFetch('/api/typesense/documents/products/id/123')PATCH /api/typesense/documents/:collection/id/:id
Update specific fields of a document.
Parameters:
collection- Collection nameid- Document ID
Request Body: Partial document with fields to update
Example:
await $fetch('/api/typesense/documents/products/id/123', {
method: 'PATCH',
body: {
price: 899.99,
inStock: true
}
})DELETE /api/typesense/documents/:collection/id/:id
Delete a specific document.
Parameters:
collection- Collection nameid- Document ID
Example:
await $fetch('/api/typesense/documents/products/id/123', {
method: 'DELETE'
})API Keys
Admin API Key Required
Key management endpoints require an admin API key. Use these carefully and only in server-side code.
GET /api/typesense/keys
Retrieve all API keys.
Example:
const { data: keys } = await useFetch('/api/typesense/keys')POST /api/typesense/keys
Create a new API key.
Request Body:
{
description: string
actions: string[] // e.g., ['documents:search', 'documents:get']
collections: string[] // Collections this key can access
expires_at?: number // Unix timestamp
value?: string // Custom key value (optional)
}Example:
const { data: key } = await useFetch('/api/typesense/keys', {
method: 'POST',
body: {
description: 'Search-only key',
actions: ['documents:search'],
collections: ['products'],
expires_at: Math.floor(Date.now() / 1000) + (60 * 60 * 24 * 30) // 30 days
}
})GET /api/typesense/keys/:id
Get details of a specific API key.
Parameters:
id- Key ID
Example:
const { data: key } = await useFetch('/api/typesense/keys/123')DELETE /api/typesense/keys/:id
Delete an API key.
Parameters:
id- Key ID
Example:
await $fetch('/api/typesense/keys/123', {
method: 'DELETE'
})Scoped API Keys
POST /api/typesense/key/scoped/:key
Generate a scoped search key that restricts a parent search key with additional search parameters. This is useful for implementing row-level security or user-specific search restrictions.
Parameters:
key- Parent search API key
Request Body: Search parameters to embed in the scoped key
{
filter_by?: string
expires_at?: number
// ... other search parameters
}Response: Base64-encoded scoped key string
Example:
// Generate a scoped key that only allows searching products in a specific category
const { data: scopedKey } = await useFetch('/api/typesense/key/scoped/xyz123abc', {
method: 'POST',
body: {
filter_by: 'category:=Electronics AND user_id:=42',
expires_at: Math.floor(Date.now() / 1000) + 3600 // 1 hour
}
})
// Use the scoped key in client-side searches
// This key can only search Electronics where user_id = 42Use Case
Scoped keys are perfect for multi-tenant applications where you need to ensure users can only search their own data without revealing the filtering logic to the client.
Stemming Dictionaries
GET /api/typesense/stemming/dictionaries
Returns { dictionaries: string[] }.
GET /api/typesense/stemming/dictionaries/:dictionaryId
Returns { id, words: [{ word, root }] }.
POST /api/typesense/stemming/dictionaries/import
Creates or replaces a dictionary. body is JSON Lines text with one word and root pair per line.
await $fetch('/api/typesense/stemming/dictionaries/import', {
method: 'POST',
body: {
id: 'my_stems',
body: '{"word":"people","root":"person"}\n{"word":"mice","root":"mouse"}',
},
})Typesense has no endpoint to delete a dictionary once it is imported.
Error Handling
All routes may return errors with the following structure:
{
statusCode: number,
message: string
}Common error codes:
400- Bad Request (missing parameters)401- Unauthorized (invalid API key)404- Not Found (collection/document doesn't exist)409- Conflict (collection already exists)500- Server Error
Example with error handling:
try {
const { data, error } = await useFetch('/api/typesense/collections', {
method: 'POST',
body: newCollection
})
if (error.value) {
console.error('Failed to create collection:', error.value.message)
}
} catch (err) {
console.error('Network error:', err)
}Usage Tips
Using $fetch vs useFetch
- Use
useFetchfor data fetching in components (provides reactivity and SSR support) - Use
$fetchfor imperative operations like create, update, delete
// Good for data fetching
const { data, pending, refresh } = await useFetch('/api/typesense/collections')
// Good for mutations
await $fetch('/api/typesense/collections', {
method: 'POST',
body: newCollection
})Server-Side Usage
You can also use these routes in server-side code:
// In a server route or API handler
export default defineEventHandler(async (event) => {
// This works in server context too
const collections = await $fetch('/api/typesense/collections')
return collections
})Type Safety
All routes work with the TypeScript types exported by the module:
import type { CollectionSchema, SearchParameters } from '#nuxt-typesense'
const schema: CollectionSchema = {
name: 'products',
fields: [
{ name: 'id', type: 'string' },
{ name: 'name', type: 'string' }
]
}
await $fetch('/api/typesense/collections', {
method: 'POST',
body: schema
})See Also
- Composables - Client-side composables for working with these routes
- Search Guide - Detailed guide on search functionality
- Collections Guide - Working with collections
- Documents Guide - Managing documents