• Blog
  • Docs
  • Pricing
  • We’re hiring!
Log inSign up
kamenxrider

kamenxrider

slimarmor

Semantic vector DB on Val Town SQLite — DiskANN, hybrid search
Public
Like
slimarmor
Home
Code
7
CHANGES.md
GUIDE.md
HANDOVER.md
README.md
H
api.ts
ui.ts
vectordb.ts
Environment variables
4
Branches
1
Pull requests
Remixes
History
Val Town is a collaborative website to build and scale JavaScript apps.
Deploy APIs, crons, & store data – all from the browser, and deployed in milliseconds.
Sign up now
Code
/
GUIDE.md
Code
/
GUIDE.md
Search
2/3/2026
Viewing readonly version of main branch: v68
View latest version
GUIDE.md

SlimArmor: How To Guide (For Dummies)

A step-by-step guide to using SlimArmor, your personal vector database for semantic search.


What Is This?

SlimArmor lets you store text and search it by meaning, not just keywords.

Example:

  • You store: "Dogs are loyal companions"
  • You search: "furry pets"
  • It finds the dog text, even though the words are different!

This is called semantic search and it's powered by AI embeddings.


Step 1: Get Your API Endpoint

Your SlimArmor API lives at:

https://kamenxrider--95fbe492ffe111f0bee942dde27851f2.web.val.run

Open that in a browser to see all available endpoints.


Step 2: Add Your First Record

To add text to the database, send a POST request:

curl -X POST https://YOUR_ENDPOINT/upsert \ -H "Content-Type: application/json" \ -d '{ "id": "note-1", "text": "The quick brown fox jumps over the lazy dog", "meta": {"category": "example"} }'

What the fields mean:

  • id - Unique identifier (you choose)
  • text - The text you want to search later
  • meta - Optional extra data (tags, categories, etc.)

Step 3: Search Your Data

To find similar text:

curl -X POST https://YOUR_ENDPOINT/search \ -H "Content-Type: application/json" \ -d '{"query": "animals jumping"}'

Response:

{ "results": [ { "id": "note-1", "text": "The quick brown fox jumps over the lazy dog", "distance": 0.52 } ] }

The distance tells you how similar it is:

  • 0.0 = Exact match
  • 0.5 = Related
  • 1.0 = Not related

Step 4: Filter by Relevance

To only get highly relevant results, add maxDistance:

curl -X POST https://YOUR_ENDPOINT/search \ -H "Content-Type: application/json" \ -d '{"query": "animals jumping", "maxDistance": 0.6}'

This filters out anything with distance > 0.6.

Recommended thresholds:

  • 0.5 = Very strict (only best matches)
  • 0.6 = Balanced (good default)
  • 0.7 = Loose (more results)

Step 5: Find Your Ideal Threshold

Not sure what threshold to use? Use the calibrate endpoint:

GET /calibrate?q=your+search+query

It will analyze your data and suggest:

  • Tight - Top 3 results only
  • Balanced - Top 10 results (use this!)
  • Loose - All retrieved results

Step 6: Check Your Stats

See how much data you have:

GET /stats

Shows:

  • Total records
  • Storage used
  • Estimated capacity

Common Tasks

Delete a record

curl -X POST https://YOUR_ENDPOINT/delete \ -H "Content-Type: application/json" \ -d '{"id": "note-1"}'

Get a specific record

GET /get?id=note-1

List all record IDs

GET /list

Delete everything (careful!)

curl -X POST "https://YOUR_ENDPOINT/clear?confirm=yes"

Using in Your Code

JavaScript/TypeScript (Val Town)

import * as db from "https://esm.town/v/kamenxrider/slimarmor/vectordb.ts"; // Setup (run once) await db.setup(); // Add a record await db.upsert("my-note", "This is my important note", { tag: "work" }); // Search const results = await db.search("important information", 5, 0.6); console.log(results); // Delete await db.remove("my-note");

From Any Language (HTTP API)

Just use the HTTP endpoints with any language that can make HTTP requests.


Tips & Best Practices

1. Choose good IDs

Use descriptive IDs like blog-post-123 or note-2024-01-15 instead of just numbers.

2. Keep text focused

Shorter, focused text works better than huge documents. If you have long documents, consider splitting them into chunks.

3. Use metadata

Store extra info in meta so you can filter later:

{ "id": "doc-1", "text": "...", "meta": { "category": "tech", "date": "2024-01-15", "author": "john" } }

4. Test your threshold

Use /calibrate?q=... to find the right maxDistance for your use case.

5. Monitor storage

Check /stats periodically. You have ~47,000 records per GB.


Advanced Features (Optional)

Filter by metadata

curl -X POST https://YOUR_ENDPOINT/search \ -H "Content-Type: application/json" \ -d '{"query":"machine learning","filters":{"category":"tech"}}'

Hybrid search (vector + keyword)

curl -X POST https://YOUR_ENDPOINT/search \ -H "Content-Type: application/json" \ -d '{"query":"python","hybrid":{"enabled":true,"alpha":0.25}}'

Batch upsert

curl -X POST https://YOUR_ENDPOINT/upsert \ -H "Content-Type: application/json" \ -d '[{"id":"a","text":"one"},{"id":"b","text":"two"}]'

Chunk long documents

curl -X POST https://YOUR_ENDPOINT/upsert_chunked \ -H "Content-Type: application/json" \ -d '{"id":"doc-long","text":"...long text...","chunkSize":800,"overlap":100}'

Export / Import

curl "https://YOUR_ENDPOINT/export?limit=200&offset=0"

Choosing an Embedding Provider

SlimArmor supports multiple embedding providers. Set these in Val Town's environment variables:

Nebius (Default - Best Value)

NEBIUS_API_KEY=your-nebius-key
  • 4096 dimensions, high quality
  • Great pricing

OpenAI

EMBEDDING_PROVIDER=openai
OPENAI_API_KEY=sk-your-key
  • 1536 dimensions
  • Most popular

OpenRouter

EMBEDDING_PROVIDER=openrouter
OPENROUTER_API_KEY=your-key
  • Access to many models
  • Pay-per-use

Custom Provider

EMBEDDING_API_URL=https://your-api.com/v1/embeddings
EMBEDDING_API_KEY=your-key
EMBEDDING_MODEL=model-name
EMBEDDING_DIM=1536

⚠️ Warning: If you switch providers, you must clear and re-insert all data (embeddings are incompatible between providers).


Troubleshooting

"Missing API key" error

Make sure your API key environment variable is set:

  • Nebius: NEBIUS_API_KEY
  • OpenAI: OPENAI_API_KEY
  • OpenRouter: OPENROUTER_API_KEY

Search returns irrelevant results

Try lowering maxDistance (e.g., 0.5 instead of 0.7).

Search returns no results

  • Check if you have data: GET /stats
  • Try raising maxDistance (e.g., 0.8)
  • Try a simpler query

Slow insert times

Each insert needs an API call to generate embeddings (~460ms). This is normal.


Validation (Self-Checks)

Run:

GET /validate

To include write tests:

GET /validate?write=yes

Requires ALLOW_WRITE_TESTS=1, a valid embedding key, and auth if ADMIN_TOKEN is set.


Quick Reference

TaskEndpointMethod
Add/update record/upsertPOST
Search/searchPOST
Delete record/deletePOST
Get record/get?id=...GET
List IDs/listGET
Check health/pingGET
View stats/statsGET
Find threshold/calibrate?q=...GET
Delete all/clear?confirm=yesPOST

Example: Building a Notes Search

import * as db from "https://esm.town/v/kamenxrider/slimarmor/vectordb.ts"; // Add some notes await db.upsert("note-1", "Meeting with Bob about Q4 budget planning"); await db.upsert("note-2", "Research machine learning frameworks for project"); await db.upsert("note-3", "Call mom for her birthday on Saturday"); // Search for work stuff const workNotes = await db.search("business meetings finance", 5, 0.6); // Search for personal stuff const personalNotes = await db.search("family calls birthdays", 5, 0.6);

Need Help?

  1. Check / endpoint for all available endpoints
  2. Check /stats to see your data
  3. Use /calibrate?q=... to tune your searches

Happy searching! 🔍

FeaturesVersion controlCode intelligenceCLIMCP
Use cases
TeamsAI agentsSlackGTM
DocsShowcaseTemplatesNewestTrendingAPI examplesNPM packages
PricingNewsletterBlogAboutCareers
We’re hiring!
Brandhi@val.townStatus
X (Twitter)
Discord community
GitHub discussions
YouTube channel
Bluesky
Open Source Pledge
Terms of usePrivacy policyAbuse contact
© 2026 Val Town, Inc.