SDK Reference

Vector Search (sdk.ai.search)

Add semantic search to your application in 2 lines of code. No vector database setup, no embedding management—just ingest and search.

Quick Start

import { AerostackServer } from '@aerostack/sdk';
 
const sdk = new AerostackServer(env);
 
// Ingest content
await sdk.ai.search.ingest("Our office is located in San Francisco", { 
  type: "faq",
  metadata: { category: "locations" }
});
 
// Search semantically
const results = await sdk.ai.search.query("Where is the office?");
console.log(results[0].content); 
// "Our office is located in San Francisco"

Core Concepts

Custom Types

Define your own data types for any use case: recipe, job_listing, property, course, etc. The system is completely flexible.

Metadata Filtering

Add structured metadata to enable precise filtering alongside semantic search.

Multi-Language Support

Choose English (default, faster) or Multilingual (100+ languages).


API Reference

ingest(content, options)

Add content to the search index.

await sdk.ai.search.ingest(content: string, {
  id?: string,                      // Auto-generated UUID if omitted
  type: string,                     // Your custom type
  metadata?: Record<string, any>    // Filterable fields
});

Example:

await sdk.ai.search.ingest(
  "Mediterranean Quinoa Bowl with fresh vegetables and tahini dressing",
  {
    id: "recipe-001",
    type: "recipe",
    metadata: {
      cuisine: "mediterranean",
      difficulty: "easy",
      prep_time_mins: 25,
      dietary: ["vegetarian", "gluten-free"]
    }
  }
);

query(text, options)

Search content semantically with optional filters.

const results = await sdk.ai.search.query(text: string, {
  topK?: number,                   // Number of results (default: 5)
  types?: string[],                // Filter by types
  filter?: Record<string, any>     // Metadata filters
});

Returns:

interface SearchResult {
  id: string;
  content: string;
  score: number;        // 0-1 similarity score
  type: string;
  metadata: Record<string, any>;
}

delete(id) & deleteByType(type)

Remove content from the index.

await sdk.ai.search.delete("recipe-001");
await sdk.ai.search.deleteByType("recipe");

listTypes()

Get all data types in your project.

const types = await sdk.ai.search.listTypes();
// Returns: [{ type: 'recipe', count: 127 }, { type: 'article', count: 45 }]

configure(options)

Set project-wide search settings (call once).

await sdk.ai.search.configure({
  model: 'multilingual'  // or 'english' (default)
});

update(id, content, options?)

Update an existing indexed item by re-ingesting with the same ID. The Vectorize upsert is idempotent — this replaces the vector and metadata without creating a duplicate.

await sdk.ai.search.update('article-123', 'Updated content here...', {
  type: 'blog_post',
  metadata: { updated_at: Date.now(), version: 2 }
});

get(id)

Retrieve a specific indexed item by ID.

const { result, exists } = await sdk.ai.search.get('article-123');
if (exists) {
  console.log(result.content);
  console.log(result.metadata);
}

count(type?)

Count total indexed items, optionally filtered by type.

// Total count across all types
const { count: total } = await sdk.ai.search.count();
console.log(`${total} items indexed`);
 
// Count by type
const { count: articles } = await sdk.ai.search.count('blog_post');
const { count: recipes } = await sdk.ai.search.count('recipe');

Real-World Examples

1. Recipe Search Platform

// Ingest recipes
for (const recipe of recipes) {
  await sdk.ai.search.ingest(
    `${recipe.name}. ${recipe.description}. Ingredients: ${recipe.ingredients.join(', ')}. Instructions: ${recipe.instructions}`,
    {
      id: recipe.id,
      type: 'recipe',
      metadata: {
        cuisine: recipe.cuisine,
        difficulty: recipe.difficulty,
        prep_time_mins: recipe.prepTime,
        cook_time_mins: recipe.cookTime,
        dietary: recipe.dietary,  // ['vegan', 'gluten-free']
        rating: recipe.averageRating
      }
    }
  );
}

2. Job Board

// Ingest job listings
await sdk.ai.search.ingest(
  `${job.title} at ${job.company}. ${job.description}. Required skills: ${job.requiredSkills.join(', ')}. Benefits: ${job.benefits}`,
  {
    id: job.id,
    type: 'job_listing',
    metadata: {
      company: job.company,
      location: job.location,
      remote: job.isRemote,
      employment_type: job.type,        // 'full-time', 'contract'
      salary_min: job.salaryRange.min,
      salary_max: job.salaryRange.max,
      experience_level: job.experienceLevel,
      skills: job.requiredSkills,
      posted_date: job.postedAt
    }
  }
);

3. E-Learning Platform

// Ingest courses
await sdk.ai.search.ingest(
  `${course.title}. ${course.description}. Topics covered: ${course.topics.join(', ')}. Learning outcomes: ${course.outcomes.join(', ')}`,
  {
    id: course.id,
    type: 'course',
    metadata: {
      category: course.category,
      level: course.level,              // 'beginner', 'intermediate', 'advanced'
      duration_hours: course.duration,
      instructor: course.instructor,
      rating: course.rating,
      price: course.price,
      language: course.language,
      skills: course.skillsTaught
    }
  }
);

4. Real Estate Listings

// Ingest property listings
await sdk.ai.search.ingest(
  `${property.title}. ${property.description}. Features: ${property.features.join(', ')}. Neighborhood: ${property.neighborhood}`,
  {
    id: property.id,
    type: 'property',
    metadata: {
      property_type: property.type,     // 'house', 'apartment', 'condo'
      bedrooms: property.bedrooms,
      bathrooms: property.bathrooms,
      sqft: property.squareFeet,
      price: property.price,
      city: property.city,
      neighborhood: property.neighborhood,
      features: property.features,      // ['pool', 'garage', 'garden']
      year_built: property.yearBuilt,
      status: property.status           // 'for_sale', 'for_rent'
    }
  }
);

5. Support Documentation / FAQ

// Ingest help articles
await sdk.ai.search.ingest(
  `Q: ${article.question}\nA: ${article.answer}`,
  {
    id: article.id,
    type: 'support_article',
    metadata: {
      category: article.category,       // 'billing', 'account', 'technical'
      subcategory: article.subcategory,
      views: article.viewCount,
      helpful_votes: article.helpfulVotes,
      updated_at: article.updatedAt
    }
  }
);

6. E-Commerce Products

// Ingest products
await sdk.ai.search.ingest(
  `${product.name}. ${product.description}. Specifications: ${product.specs}`,
  {
    id: product.id,
    type: 'product',
    metadata: {
      category: product.category,
      brand: product.brand,
      price: product.price,
      in_stock: product.inStock,
      rating: product.averageRating,
      review_count: product.reviewCount,
      tags: product.tags,
      color: product.color,
      size: product.size
    }
  }
);

7. Blog / Content Platform

// Ingest blog posts
await sdk.ai.search.ingest(
  `${post.title}. ${post.excerpt}. ${post.content}`,
  {
    id: post.id,
    type: 'blog_post',
    metadata: {
      author: post.author,
      category: post.category,
      tags: post.tags,
      published_at: post.publishedAt,
      read_time_mins: post.readTime,
      views: post.viewCount
    }
  }
);

8. Event Management

// Ingest events
await sdk.ai.search.ingest(
  `${event.name}. ${event.description}. Speakers: ${event.speakers.join(', ')}. Topics: ${event.topics.join(', ')}`,
  {
    id: event.id,
    type: 'event',
    metadata: {
      category: event.category,         // 'conference', 'workshop', 'webinar'
      format: event.format,             // 'in-person', 'virtual', 'hybrid'
      start_date: event.startDate,
      end_date: event.endDate,
      location: event.location,
      ticket_price: event.ticketPrice,
      capacity: event.capacity,
      spots_remaining: event.spotsRemaining,
      tags: event.tags
    }
  }
);

9. Restaurant / Menu Items

// Ingest menu items
await sdk.ai.search.ingest(
  `${item.name}. ${item.description}. Ingredients: ${item.ingredients.join(', ')}`,
  {
    id: item.id,
    type: 'menu_item',
    metadata: {
      restaurant: item.restaurantId,
      category: item.category,          // 'appetizer', 'main', 'dessert'
      cuisine: item.cuisine,
      price: item.price,
      spice_level: item.spiceLevel,
      dietary: item.dietary,            // ['vegetarian', 'gluten-free']
      popular: item.orderCount > 100,
      rating: item.rating
    }
  }
);

10. Medical / Health Resources

// Ingest health articles
await sdk.ai.search.ingest(
  `${article.title}. ${article.summary}. Symptoms: ${article.symptoms.join(', ')}. Treatments: ${article.treatments.join(', ')}`,
  {
    id: article.id,
    type: 'health_article',
    metadata: {
      category: article.category,       // 'nutrition', 'fitness', 'mental_health'
      condition: article.condition,
      reviewed_by: article.reviewer,
      last_updated: article.lastUpdated,
      evidence_level: article.evidenceLevel,  // 'high', 'moderate', 'low'
      audience: article.audience        // 'general', 'professional'
    }
  }
);

Advanced Filtering

Comparison Operators

// Greater than / Less than
await sdk.ai.search.query("affordable products", {
  types: ['product'],
  filter: {
    price: { $lte: 50 },           // Less than or equal
    rating: { $gte: 4.0 }          // Greater than or equal
  }
});
 
// Range queries
await sdk.ai.search.query("mid-size sedan", {
  types: ['car'],
  filter: {
    price: { $gte: 20000, $lte: 35000 },
    year: { $gte: 2020 }
  }
});

Array Filters

// Contains (any match)
await sdk.ai.search.query("vegetarian recipe", {
  types: ['recipe'],
  filter: {
    dietary: { $contains: 'vegetarian' }
  }
});
 
// Contains all
await sdk.ai.search.query("full-stack developer", {
  types: ['job_listing'],
  filter: {
    skills: { $containsAll: ['React', 'Node.js', 'PostgreSQL'] }
  }
});
// Search across multiple types
const results = await sdk.ai.search.query("javascript tutorial", {
  types: ['blog_post', 'course', 'video'],
  topK: 20
});

Multi-Language Setup

Switch to multilingual embeddings for 100+ language support:

await sdk.ai.search.configure({
  model: 'multilingual'
});
 
// Now ingest and search in any language
await sdk.ai.search.ingest("Cómo hacer paella valenciana", {
  type: 'recipe',
  metadata: { language: 'es', cuisine: 'spanish' }
});
 
const results = await sdk.ai.search.query("paella recipe", {
  types: ['recipe']
});
// Works across languages!

English model: Faster, lower cost, optimized for English content.
Multilingual model: Supports 100+ languages, cross-language search.


Best Practices

1. Content Formatting

Structure your content for better search results:

// ✅ Good: Rich, descriptive content
await sdk.ai.search.ingest(
  `${product.name}. ${product.description}. Key features: ${features.join(', ')}. Use cases: ${useCases.join(', ')}`,
  { type: 'product', metadata: {...} }
);
 
// ❌ Avoid: Minimal content
await sdk.ai.search.ingest(product.name, { type: 'product' });

2. Metadata Design

Use metadata for precise filtering:

// ✅ Good: Structured, filterable metadata
metadata: {
  category: 'electronics',
  price: 599,
  in_stock: true,
  rating: 4.5
}
 
// ❌ Avoid: Putting filterable data only in content
content: "Price: $599, In Stock, 4.5 stars"

3. Type Naming

Use clear, consistent type names:

// ✅ Good
type: 'job_listing'
type: 'blog_post'
type: 'support_article'
 
// ❌ Avoid
type: 'jobs'
type: 'post'
type: 'help'

Quotas & Limits

PlanIngest/monthSearches/month
Free1,000 items10,000 searches
Pro50,000 items100,000 searches
EnterpriseUnlimitedUnlimited
⚠️

Quota exceeded errors will return HTTP 429. Monitor usage in your Admin dashboard.


Performance Tips

  • Batch ingestion: Ingest multiple items in parallel for faster indexing
  • topK limits: Start with topK: 5-10 for faster searches
  • Metadata first: Use metadata filters before semantic search when possible
  • Content length: Keep content between 100-1000 characters for optimal results