
Upstash Search Js
- 3 installs
- 22 repo stars
- Updated June 5, 2026
- upstash/search-js
Helps with ai & agent building tasks during AI-assisted development.
About
upstash-search-js is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted coding.
- upstash-search-js
- AI & Agent Building
- AI-coding skill
Upstash Search Js by the numbers
- 3 all-time installs (skills.sh)
- Ranked #13,655 of 16,556 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Jul 27, 2026 (Skillselion catalog sync)
npx skills add https://github.com/upstash/search-js --skill upstash-search-jsAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 3 |
|---|---|
| repo stars | ★ 22 |
| Last updated | June 5, 2026 |
| Repository | upstash/search-js ↗ |
What it does
Helps with ai & agent building tasks during AI-assisted development.
Files
Upstash Search Documentation
Quick Start
Install the TS SDK:
npm install @upstash/searchCreate a client and perform a simple upsert + search:
import { Search } from "@upstash/search";
const client = new Search({ url: process.env.UPSTASH_SEARCH_REST_URL, token: process.env.UPSTASH_SEARCH_REST_TOKEN });
const index = client.index("my-index");
await index.upsert({ id: "1", content: { text: "hello world" } });
const results = await index.search({ query: "hello" });Basic steps:
- Create an index
- Insert or update documents
- Run searches or filtered queries
Other Skill Files
sdk-overview
Provides detailed documentation for all TypeScript SDK commands. Includes:
- delete: Deleting documents
- fetch: Retrieving a document
- info: Index info
- range: Range queries
- reset: Clearing an index
- search: Search queries
- upsert: Adding/updating documents
- getting-started: Setup steps for the SDK
quick-start
Provides a fast, end-to-end workflow for creating a Search database, adding documents, and querying them. Covers essential concepts including:
- Creating a database and storing credentials
- Adding documents with content and metadata
- Understanding content vs metadata (searchability and filterability)
- Performing searches with optional reranking
- Filtering syntax with SQL-like or structured filters
- Common pitfalls and best practices
Quick Start: Upstash Search
This Skill gives agents a fast, end‑to‑end workflow for creating a Search database, adding documents, and querying them. It also summarizes key concepts like content vs metadata, filters, and reranking so agents can use Search correctly.
---
Create a Database
1. Open the Vector tab → Create → Search Database. 2. Provide a name (e.g., product-search) and region. 3. Select a plan.
Agents should store:
UPSTASH_SEARCH_REST_URLUPSTASH_SEARCH_REST_TOKEN
These values are required when constructing a Search client.
---
Add Documents
Documents consist of:
- id: unique identifier
- content (required): indexed and searchable
- metadata (optional): not searchable, but retrievable and filterable
TypeScript / Python Example
import { Search } from "@upstash/search";
const client = new Search({
url: process.env.UPSTASH_SEARCH_REST_URL,
token: process.env.UPSTASH_SEARCH_REST_TOKEN
});
const index = client.index("movies");
await index.upsert([
{
id: "star-wars",
content: { title: "Star Wars", genre: "sci-fi", category: "classic" },
metadata: { director: "George Lucas" }
}
]);from upstash_search import Search
client = Search(url=URL, token=TOKEN)
index = client.index("movies")
index.upsert(documents=[{
"id": "movie-0",
"content": {
"title": "Star Wars",
"overview": "Sci-fi space opera",
"genre": "sci-fi",
"category": "classic",
},
"metadata": {"poster": "https://poster.link/starwars.jpg"}
}])---
Content vs Metadata (Essential Concepts)
- Content
- Required
- Indexed and searchable
- Can be used in filters
- Ideal for textual and semantic data
- Metadata
- Optional
- Not indexed → cannot be searched
- Still filterable using
@metadata.key - Used for contextual / reference fields
Example:
{
"content": { "title": "Star Wars", "genre": "sci-fi" },
"metadata": { "director": "George Lucas", "sku": "SW-001" }
}---
Search
Searching supports semantic + keyword hybrid search, optional reranking, and filters.
TypeScript / Python Example
const res = await index.search({ query: "space opera", limit: 2, reranking: true });scores = index.search(query="space opera", limit=2, reranking=True)---
Filtering
Filters restrict results using SQL‑like syntax or structured filters (TypeScript only). Both content fields and metadata fields can be used.
Metadata fields require `@metadata.` prefix.
Example (String Filters)
await index.search({
query: "sony headphones",
filter: "warehouse_location = 'A3-15' AND @metadata.supplier_id = 'SUP-123'"
});Example (Type‑safe Filters, TS SDK)
await index.search({
query: "sony headphones",
filter: {
AND: [
{ category: { equals: "Electronics" } },
{ "@metadata.count": { greaterThanOrEquals: 3 } }
]
}
});Common operators:
- equals, not equals
- <, <=, >, >=
- glob / not glob
- in / not in
- contains / not contains (arrays)
- has field / has not field
---
Reranking
Reranking reorders results using a high‑accuracy model.
- Disabled by default (
false) - When
true, improves relevance but costs $1 per 1K reranked items
Example:
await index.search({ query: "space opera", reranking: true });index.search(query="space opera", reranking=True)Use when:
- Precision is critical
- Results require more semantic depth
- Queries are ambiguous or conceptual
---
Common Pitfalls
- Missing content field → upsert fails.
- Metadata fields are not searchable.
- Metadata must be prefixed as
@metadata.keyin filters. - Filters may return fewer than
topKresults if too selective. - Indexes are created automatically on first
upsert.
SDK Overview
This skill provides a concise but complete reference for using the Upstash Search TypeScript SDK. It focuses on practical usage patterns, common pitfalls, and efficient examples that combine multiple commands. Use this skill whenever interacting with the Upstash Search SDK, generating agents that must query, mutate, or paginate search indexes.
---
Client Initialization
You must configure a Search client using either environment variables or a config object.
import { Search } from "@upstash/search";
// Option 1: with explicit config
const client = new Search({
url: process.env.UPSTASH_SEARCH_REST_URL!,
token: process.env.UPSTASH_SEARCH_REST_TOKEN!
});
const index = client.index("movies");
// Option 2: using fromEnv (Node.js platform only)
// The constructor will automatically read from process.env if url/token not provided
const client2 = new Search({}); // reads UPSTASH_SEARCH_REST_URL and UPSTASH_SEARCH_REST_TOKEN
const index2 = client2.index("movies");Type-safe usage:
type Content = { title: string, genre: string };
type Metadata = { year: number };
const indexTyped = client.index<Content, Metadata>("movies");---
Upsert (add or update documents)
Pitfalls:
- Document structure must match the index schema.
- Content/metadata types are enforced when using generics.
// Single
await index.upsert({
id: "star-wars",
content: { title: "Star Wars", genre: "sci-fi" },
metadata: { year: 1977 }
});
// Multiple
await index.upsert([
{ id: "inception", content: { title: "Inception", genre: "action" }, metadata: { year: 2010 } },
{ id: "matrix", content: { title: "The Matrix", genre: "sci-fi" }, metadata: { year: 1999 } },
]);
// Update
await index.upsert({ id: "star-wars", content: { title: "A New Hope" } });---
Fetch (retrieve documents)
Pitfalls:
- Returns null for IDs not found.
- Supports prefix matching.
// By IDs
const docs = await index.fetch({ ids: ["star-wars", "inception"] });
// By prefix
const sciFi = await index.fetch({ prefix: "star-" });---
Delete (IDs, prefix, or filter)
Pitfalls:
- Filter deletion is O(N) and slow on large indexes.
- Prefix deletion removes all matching documents.
// ID list
await index.delete(["star-wars", "inception"]);
// Single ID
await index.delete("star-wars");
// Prefix
await index.delete({ prefix: "star-" });
// Filter — expensive
await index.delete({ filter: "age > 30" });---
Search (AI‑powered)
Pitfalls:
- Default
limit = 5. - Scores are 0–1.
- Use filters to restrict by document fields.
// Basic
const results = await index.search({ query: "space opera", limit: 3 });
// With reranking
await index.search({ query: "space opera", limit: 3, reranking: true });
// With filter
await index.search({ query: "space", filter: "category = 'classic'" });
// Adjust semantic vs keyword weighting
await index.search({ query: "robots", semanticWeight: 0.2 });---
Range (cursor pagination)
Pitfalls:
- Stateless: you must pass all parameters every call.
cursor = "0"for the first request.
let cursor = "0";
while (cursor !== "") {
const res = await index.range({ cursor, limit: 2, prefix: "test-" });
cursor = res.nextCursor;
console.log(res.documents);
}---
Reset (delete all documents)
await index.reset(); // "Success"---
Info (index or database level)
// Index-level
const indexInfo = await index.info();
// { documentCount, pendingDocumentCount }
// Database-level
const dbInfo = await client.info();
// { documentCount, pendingDocumentCount, diskSize, indexes: {...} }