API & SDKs

21 endpoints. JSON in, JSON out. Three verbs: Show (paste examples), Get (find a recipe), Run (call it). The whole API surface fits on one screen of code — see the SDK at the bottom.

5-minute integration

# 1. install (or skip and use curl)
npm install @kolmogorov/recipe        # Node
pip install kolmogorov-recipe         # Python

# 2. mint a free key (10k calls/month, no card)
KS=$(curl -sX POST https://kolmogorov-stack-production.up.railway.app/v1/signup \
  -H "Content-Type: application/json" -d '{"email":"you@company.com"}' \
  | python -c "import sys,json;print(json.load(sys.stdin)['api_key'])")

# 3. show it your examples (paste 4-8)
curl -X POST https://kolmogorov-stack-production.up.railway.app/v1/synthesize \
  -H "Authorization: Bearer $KS" -H "Content-Type: application/json" \
  -d '{
    "name": "classify-issue-type",
    "output_spec": { "type": "enum", "values": ["bug","feature","question"] },
    "positives": [
      { "input": "deploy keeps crashing on startup", "expected": "bug" },
      { "input": "would love an export to CSV",     "expected": "feature" },
      { "input": "how do I rotate my API key?",     "expected": "question" }
    ]
  }'
# → { accepted: true, concept_id: "cpt_…", quality_score: 1.0 }

# 4. run it forever
curl -X POST https://kolmogorov-stack-production.up.railway.app/v1/run \
  -H "Authorization: Bearer $KS" -H "Content-Type: application/json" \
  -d '{ "concept_id": "cpt_…", "input": "404 on /dashboard" }'
# → { output: "bug", latency_us: 41, cache: null }

Auth

Authorization: Bearer ks_…       # tenant key (mint via /v1/signup)
X-API-Key: ks_…                  # alternative header
Authorization: Bearer ks_admin_… # admin only, provisions tenants

POST /v1/signup public

Mint a tenant + key for free. 10,000 calls/month included. No card.

{ "email": "you@company.com", "name": "acme" (optional) }
→ { "api_key": "ks_…", "tenant": { "id": "tenant_…", "plan": "free", "quota": 10000, "used": 0 } }

GET /v1/account

Returns the calling tenant's plan, quota, used, remaining.

POST /v1/account/rotate-key

Rotate this tenant's key. Old key stops working immediately.

Show — synthesis

Paste examples, get back a tested recipe. (legacy alias: /v1/synthesize; both names work.)

POST /v1/synthesize

Synthesize a recipe from positive and negative examples. Optionally publishes to your registry.

{
  "name": "classify-issue-type",
  "tags": ["classifier","support"],
  "visibility": "private" | "public",
  "publish": true,
  "output_spec": { "type": "enum", "values": ["bug","feature","question"] },
  "positives": [ { "input": "...", "expected": ... }, ... ],
  "negatives": [ { "input": "...", "expected_not": ... }, ... ],
  "priors": { "hint": "free text", "max_size_bytes": 2048 }
}

→ {
  "accepted": true,
  "concept_id": "cpt_…",
  "version_id": "ver_…",
  "quality_score": 0.94,
  "pass_rate_positive": 1.0,
  "reject_rate_negative": 1.0,
  "latency_p50_us": 87,
  "size_bytes": 412,
  "source": "function generate(input, lib) { … }",
  "source_hash": "…",
  "strategy": "claude" | "pattern",
  "test_trace": [ { kind, input, output, pass, latency_us } ],
  "attempts_n": 1,
  "duration_ms": 2114
}

POST /v1/synthesize/stream

SSE stream of synthesis events: start, plan, strategy_begin, candidate, verified, accepted, published, done.

const res = await fetch('/v1/synthesize/stream', { method:'POST',
  headers:{ Authorization:'Bearer '+key, 'Content-Type':'application/json' },
  body: JSON.stringify({...}) });
const reader = res.body.getReader();
// parse "event: ...\ndata: {...}\n\n" frames

POST /v1/synthesize/batch

Up to 25 recipes in one request. Sequential synthesis, single round-trip.

{ "items": [ { "name": "...", "positives": [...], "output_spec": {...} }, ... ] }

POST /v1/verify

Re-run a recipe's test trace without publishing.

{ "source": "function generate(...){...}", "positives":[...], "negatives":[...] }

POST /v1/publish

Publish a hand-edited recipe straight to the registry. Verifies in flight.

{ "name": "my-recipe", "source": "function generate(input,lib){...}", "positives":[...], "negatives":[...], "tags":["..."] }

Get — registry

GET /v1/concepts ?tag=&limit=

List recipes owned by your tenant.

GET /v1/concepts/:id

Fetch a recipe and its versions.

GET /v1/concepts/:id/stats

Per-recipe usage: invocation count, latency p50/p95/p99, cache hit rate, error rate, last_invoked_at.

DELETE /v1/concepts/:id

GET /v1/concepts/:id/lineage

Upstream synthesizers and downstream dependents.

POST /v1/search

Semantic search by what the recipe does. Type "extract email addresses" — not the exact name.

{ "query": "find recipes about extracting prices", "k": 10, "tag": "extractor" }
→ { "matches": [ { concept_id, name, score, version_id, ... }, ... ] }

GET /v1/public/concepts public

GET /v1/public/concepts/:id public

POST /v1/public/run public

Dispatch any public recipe. No auth needed. Convenient for embedded demos.

Run — runtime

POST /v1/run

Dispatch a single recipe (head version) or a specific version. Output is cached for identical input.

{ "concept_id": "cpt_…",   "input": "any json", "use_cache": true }
{ "version_id": "ver_…",   "input": "any json" }
→ { "output": ..., "latency_us": 87, "cache": null | "L1" | "L2", "version_id": "...", "concept": "..." }

POST /v1/compose

Search top-K recipes by query, dispatch them in parallel, compose outputs with one of four strategies.

{
  "query": "classify intent",
  "input": "where is my order",
  "k": 5,
  "strategy": "attention" | "voting" | "top1" | "sequential",
  "tag": "classifier"
}

→ {
  "output": "question",
  "dispatched": [ { name, concept_id, score, output, latency_us, cache }, ... ],
  "strategy": "attention"
}

GET /v1/telemetry

Total invocations, average latency, p50/p95/p99, cache hit-rate, recent invocation log, sparkline.

GET /v1/library

The current built-in subroutine library — version + signatures.

SDKs

Pick your language. The TypeScript and Python clients are the supported ones; the Go and Java snippets below are minimal but production-shaped.

Node / TypeScript

// npm install @kolmogorov/recipe
import { Recipe } from '@kolmogorov/recipe';

const r = new Recipe({ apiKey: process.env.KS_KEY });

// teach once
const recipe = await r.show('classify-issue-type', {
  examples: [
    { input: 'deploy keeps crashing', expected: 'bug' },
    { input: 'love an export button',  expected: 'feature' },
    { input: 'how do I rotate keys?',  expected: 'question' },
  ],
  shape: { type: 'enum', values: ['bug','feature','question'] },
});

// run forever
console.log(await r.run(recipe.id, '404 on /dashboard'));  // 'bug'

Python

# pip install kolmogorov-recipe
from kolmogorov_recipe import Recipe

r = Recipe(api_key=os.environ['KS_KEY'])

recipe = r.show(
  name='classify-issue-type',
  examples=[
    {'input': 'deploy crashes',   'expected': 'bug'},
    {'input': 'export to csv',    'expected': 'feature'},
    {'input': 'rotate key?',      'expected': 'question'},
  ],
  shape={'type': 'enum', 'values': ['bug','feature','question']},
)

print(r.run(recipe['concept_id'], '404 on /dashboard'))   # 'bug'

Go

// HTTP, no SDK needed
req, _ := http.NewRequest("POST",
  "https://kolmogorov-stack-production.up.railway.app/v1/run",
  bytes.NewBufferString(`{"concept_id":"cpt_…","input":"404 on /dashboard"}`))
req.Header.Set("Authorization", "Bearer "+os.Getenv("KS_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)

Java

HttpRequest req = HttpRequest.newBuilder()
  .uri(URI.create("https://kolmogorov-stack-production.up.railway.app/v1/run"))
  .header("Authorization", "Bearer " + System.getenv("KS_KEY"))
  .header("Content-Type", "application/json")
  .POST(HttpRequest.BodyPublishers.ofString(
    "{\"concept_id\":\"cpt_…\",\"input\":\"404 on /dashboard\"}"))
  .build();

Claude Code MCP server

Drop-in MCP server: npx @kolmogorov/recipe-mcp. Adds recipe.show, recipe.run, recipe.search to your Claude Code session.

# in your ~/.claude/mcp.json
{
  "mcpServers": {
    "recipe": {
      "command": "npx",
      "args": ["-y","@kolmogorov/recipe-mcp"],
      "env": { "KS_API_KEY": "ks_…" }
    }
  }
}

Errors

codemeaning
400missing required field, bad JSON, or recipe quality below gate
401missing or invalid API key
403tenant cannot read this recipe; admin-only endpoint hit by non-admin
404recipe or version not found
429rate limit (token bucket) or monthly quota exceeded — see Retry-After
500synthesis backend error

Pricing details: /pricing. Status / changelog: /status.