SentinelMeshAI Documentation

Complete reference for the SentinelMeshAI AI Gateway — multi-model routing, self-learning optimisation, and enterprise-grade orchestration.

● API Operational Version 1.0.0 Updated April 2026
Intelligent Routing
Bandit + reinforcement learning automatically selects the best model and strategy per request — and gets smarter every call.
Semantic Cache
Identical and semantically similar queries are served from cache. 40–60% cost reduction from day one, zero configuration.
Enterprise Security
Per-tenant rate limits, usage budgets, API key scoping, audit logs, and PII guardrails built into every request path.
Progressive Independence
The platform trains custom self-models on your data. Over time, external LLM calls drop by up to 89% while quality holds.
40+ Integrations
Slack, GitHub, Salesforce, Notion, Stripe, PostgreSQL, Redis, and more — connect any workflow in minutes.
Unified Multi-Model
OpenAI, Anthropic, Google, Mistral, DeepSeek, Cohere, Groq — one API surface, all frontier models.

Core Concepts

Before integrating, these five concepts explain what SentinelMeshAI does differently from a direct LLM API call.

Request Lifecycle

Your App → API Gateway
Auth · Rate limit
→ Semantic Cache
Hit? Return now
→ Bandit Router
Select strategy
→ LLM Adapters
1–5 models
→ RL Update
Learn reward
→ Response

Strategies

A strategy defines which models to call and how to combine their answers. The router automatically selects the best strategy per request based on learned performance. You can also request a strategy explicitly.

StrategyModels calledBest forApprox. cost
fast_cheapDeepSeek ChatHigh-volume, cost-critical$0.00014/1K tok
standardClaude 3.5 SonnetGeneral-purpose, best value$0.003/1K tok
fast_reasoningo3-miniMath, logic, structured output$0.0011/1K tok
code_specialistCodestralCode generation & review$0.0002/1K tok
rag_specialistCommand-R-PlusRAG, retrieval, long docs$0.0025/1K tok
parallel_ensembleGPT-4.1 + Claude + Gemini + DeepSeek + GroqCritical decisions, consensus~$0.006/1K tok
high_accuracyGPT-4.1 + Claude 3.7 + Gemini 2.5 Pro + o1Maximum accuracy, frontier tasks~$0.025/1K tok

Tenancy & API Keys

Every API key maps to a tenant. Each tenant has its own rate limit, usage budget, billing tier, learning state, and WorldModel. Keys look like sm_live_... (production) or sm_test_... (testing, never billed).

Quickstart 5 min

Step 1 — Get your API key

Sign up at app.sentinelmeshai.com → Dashboard → API Keys → New Key. Your key starts with sm_live_.

Step 2 — First request
cURL
Python
Node.js
Go
bashcurl -X POST https://api.sentinelmeshai.com/run \
  -H "Authorization: Bearer sm_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"prompt": "Explain quantum entanglement in one paragraph."}'
pythonimport os, sentinelmeshai as sm

sm.api_key = os.getenv("SENTINELMESHAI_API_KEY")

result = sm.run("Explain quantum entanglement in one paragraph.")
print(result["output"])
# → "Quantum entanglement is a phenomenon..."
print(f"Model : {result['models_used']}")
print(f"Cost  : ${result['cost_usd']:.6f}")
print(f"Latency: {result['latency_ms']}ms")
javascriptimport SentinelMeshAI from 'sentinelmeshai';

const sm = new SentinelMeshAI({ apiKey: process.env.SENTINELMESHAI_API_KEY });

const result = await sm.run("Explain quantum entanglement in one paragraph.");
console.log(result.output);
console.log(`Cost: $${result.cost_usd.toFixed(6)}`);
console.log(`Models: ${result.models_used.join(', ')}`);
gopackage main

import (
    "fmt"
    sm "github.com/sentinelmeshai/go-sdk"
)

func main() {
    client := sm.New(sm.Config{APIKey: os.Getenv("SENTINELMESHAI_API_KEY")})
    result, _ := client.Run("Explain quantum entanglement in one paragraph.")
    fmt.Println(result.Output)
    fmt.Printf("Cost: $%.6f\n", result.CostUSD)
}
Expected Response
{
  "output": "Quantum entanglement is a phenomenon where two particles...",
  "models_used": ["anthropic:claude-3-5-sonnet-20241022"],
  "strategy_used": "standard",
  "cost_usd": 0.000843,
  "latency_ms": 412,
  "confidence": 0.97,
  "cached": false,
  "trace_id": "tr_8f3a2b91c4d05e67"
}

Authentication

All requests require a Bearer token in the Authorization header.

httpAuthorization: Bearer sm_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
⚠️ Never expose your key
Always load from environment variables. Never commit to git. Frontend apps must proxy through your backend — the key must never reach the browser.
HeaderValueRequired
AuthorizationBearer sm_live_...required
Content-Typeapplication/jsonrequired
X-Request-IDYour trace ID (e.g. UUID)optional
X-Session-IDPersistent session for memoryoptional

Platform Architecture

FastAPI Engine (v1.0)

The AI engine handles all LLM calls. It exposes 84 HTTP endpoints covering inference, streaming, vision, voice, workflows, benchmarks, and admin operations. It persists all state (tenants, billing, WorldModel, traces) to SQLite volumes — no external DB required.

Django Webapp (v2)

The customer-facing platform. Handles auth, billing (Stripe), dashboard, admin portal, and plan management. Syncs tenants to the FastAPI engine via private internal networking on first registration and on plan upgrades.

SDK Layer (PyPI / npm)

Thin client libraries for Python and Node.js. Wraps the HTTP API with typed methods, error classes, streaming helpers, and async support. No runtime dependencies beyond httpx (Python) or the fetch API (Node).

AI Router — Bandit + Reinforcement Learning

The router uses a contextual LinUCB bandit to select the strategy for each request. After the response is returned, it observes a reward signal (response quality × inverse cost) and updates arm weights. Over time, it learns which strategies work best for your specific workload — automatically.

python# Request a specific strategy explicitly (overrides the router)
result = await router.route(
    prompt    = "Debug this Python traceback...",
    strategy  = "code_specialist",   # pin to Codestral
    context   = {"temperature": 0.1, "max_tokens": 2048},
    tenant_id = "ten_abc123",
)

POST /run

POST
https://api.sentinelmeshai.com/run
Route a prompt through SentinelMeshAI. The router selects the optimal strategy automatically. Returns output, cost, latency, and trace.

Request body

FieldTypeDescription
promptrequiredstringThe input text to send to the model. Max 32,000 tokens.
strategyoptionalstringForce a strategy: fast_cheap, standard, parallel_ensemble, high_accuracy, etc.
temperatureoptionalfloat0.0–1.0. Default: 0.2. Higher = more creative, lower = more deterministic.
max_tokensoptionalintMaximum output tokens. Default: 1024. Max: 16384.
system_promptoptionalstringSystem-level instructions prepended to every message.
metadataoptionalobjectArbitrary key-value pairs attached to the trace (useful for analytics).

Response

FieldTypeDescription
outputstringThe model's response text.
models_usedstring[]List of adapter names that contributed (e.g. ["anthropic:claude-3-5-sonnet-20241022"]).
strategy_usedstringWhich strategy was selected.
cost_usdfloatTotal cost in USD for this request.
latency_msintEnd-to-end latency in milliseconds.
confidencefloat0.0–1.0 confidence estimate from the router.
cachedbooleantrue if the response was served from semantic cache.
trace_idstringUnique request identifier for debugging.

POST /run-with-memory

POST
https://api.sentinelmeshai.com/run-with-memory
Run a prompt with persistent session memory. The model sees previous turns in this session, enabling multi-turn conversations.

Additional fields

FieldTypeDescription
session_idrequiredstringIdentifies the conversation. Use a UUID or your own user/chat ID. Sessions persist for 7 days.
window_sizeoptionalintMax previous turns to include. Default: 10. Max: 50.
pythonSESSION = "user_12345_chat_001"

# Turn 1
r1 = sm.run_with_memory("My name is Alex.", session_id=SESSION)

# Turn 2 — model remembers "Alex"
r2 = sm.run_with_memory("What's my name?", session_id=SESSION)
print(r2["output"])  # "Your name is Alex."

POST /run-cached

POST
https://api.sentinelmeshai.com/run-cached
Explicit semantic cache request. Searches for semantically similar previous prompts (cosine similarity > 0.92) before calling any LLM. Cached hits cost $0.
python# First call — goes to LLM
r1 = sm.run_cached("What is the capital of France?")
print(r1["cached"])  # False, cost_usd: 0.000120

# Semantically similar call — served from cache
r2 = sm.run_cached("Tell me the capital city of France")
print(r2["cached"])  # True, cost_usd: 0.000000

POST /run-stream

POST
https://api.sentinelmeshai.com/run-stream
Server-sent events stream. Yields text chunks as the model generates them — eliminates the perception of latency for long responses.
pythonimport asyncio, sentinelmeshai as sm

sm.api_key = "sm_live_..."

async def stream_example():
    async for chunk in sm.astream("Write a 200-word essay on recursion."):
        print(chunk, end="", flush=True)

asyncio.run(stream_example())
javascriptconst sm = new SentinelMeshAI({ apiKey: process.env.SENTINELMESHAI_API_KEY });

const stream = await sm.stream("Write a 200-word essay on recursion.");
for await (const chunk of stream) {
  process.stdout.write(chunk);
}

GET /usage

GET
https://api.sentinelmeshai.com/usage
Returns current billing period usage: requests, tokens, cost, and remaining credits for the authenticated tenant.

Semantic Caching

SentinelMeshAI embeds every prompt using sentence-transformers/all-MiniLM-L6-v2 and compares cosine similarity against the cache. Hits with similarity > 0.92 are returned instantly at zero cost. The cache is per-tenant and persists for 24 hours.

💰 Typical savings
Customer support workloads (many similar questions) typically see 40–65% requests served from cache. FAQ-type assistants can reach 80%+ cache hit rates.
python# Use /run-cached endpoint, or add "use_cache": true to /run body
result = requests.post(API_URL + "/run-cached", ...)

# Check if cached
if result.json()["cached"]:
    print("Free! Served from semantic cache.")
else:
    print(f"LLM call — cost: ${result.json()['cost_usd']:.6f}")

Memory & Sessions

Sessions are identified by session_id. SentinelMeshAI stores the conversation window in a vector store (SQLite + in-memory embeddings) and prepends relevant context on each turn. Sessions expire after 7 days of inactivity.

ConceptDescriptionDefault
Session IDYour identifier for a conversation threadRequired by caller
Window sizeMax previous turns included in context10 turns
ExpirySessions older than N days of inactivity are pruned7 days
StoragePer-tenant SQLite on Railway VolumeAuto-provisioned

Streaming Responses

Use the /run-stream endpoint for any response longer than ~100 tokens. Streaming reduces perceived latency to near-zero and allows progressive rendering in UI components.

💡 React streaming example
Use a ReadableStream / EventSource on the frontend. The SDK's astream() (Python) and stream() (Node.js) handle SSE parsing automatically — you just iterate chunks.

Vision & Multimodal

Send images alongside prompts using base64 encoding. The vision pipeline routes to OpenAI GPT-4o (default) or Google Gemini 2.0 Flash depending on task type.

pythonimport base64, requests

with open("chart.png", "rb") as f:
    image_b64 = base64.b64encode(f.read()).decode()

result = requests.post(
    "https://api.sentinelmeshai.com/vision/analyze",
    headers={"Authorization": f"Bearer {API_KEY}"},
    json={
        "image": image_b64,
        "prompt": "Extract all data from this bar chart as JSON.",
        "vision_model": "gpt-4o"  # or "gemini-2.0-flash"
    }
).json()
print(result["output"])

Function Calling

Define tools as Python functions and register them with the ToolRegistry. The model decides when to call tools, SentinelMeshAI executes them and feeds results back — automatically, with loop protection (max 5 rounds).

pythonfrom core.tools.base_tool  import BaseTool
from core.tools.tool_registry import ToolRegistry
from core.agents.tool_agent   import ToolAgent
from app import router

class WeatherTool(BaseTool):
    name        = "get_weather"
    description = "Get current weather for a city"
    async def execute(self, city: str) -> str:
        # Call your weather API here
        return f"72°F, sunny in {city}"

registry = ToolRegistry()
registry.register(WeatherTool())

agent = ToolAgent("assistant", router=router, tool_registry=registry)
result = await agent.run("What's the weather in Lagos right now?")
print(result.output)  # "It is currently 72°F and sunny in Lagos."

Webhooks

SentinelMeshAI can push events to your endpoint when key things happen: model training completes, usage thresholds are crossed, or benchmarks detect regressions.

python# Register a webhook (POST /admin/webhook — requires X-Admin-Key)
requests.post(
    "https://api.sentinelmeshai.com/admin/webhook",
    headers={"X-Admin-Key": ADMIN_KEY},
    json={
        "url":    "https://yourapp.com/webhooks/sentinelmeshai",
        "events": ["model.trained", "usage.threshold", "benchmark.regression"],
        "secret": "your_webhook_secret"
    }
)
Webhook payload shape
Every webhook POST contains event, timestamp, tenant_id, and data. Verify the X-Webhook-Signature header (HMAC-SHA256 of the raw body using your secret) before processing.

Error Codes

401 Unauthorized
Missing or invalid API key. Check your Authorization: Bearer header.
403 Forbidden
Key is valid but you're accessing an admin endpoint without admin privileges.
429 Too Many Requests
Rate limit exceeded. Check your plan's RPM limit. Back off exponentially. The Retry-After header gives seconds to wait.
402 Payment Required
Monthly credit limit reached. Upgrade your plan or wait for the next billing cycle.
422 Unprocessable Entity
Request body is valid JSON but fails validation. Check the detail array in the response for field-level errors.
503 Service Unavailable
All upstream LLM providers returned errors simultaneously. This is very rare. Retry with exponential backoff.

Retries & Timeouts

pythonimport httpx, time

def call_with_retry(prompt, max_retries=3):
    for attempt in range(max_retries):
        try:
            r = httpx.post(
                "https://api.sentinelmeshai.com/run",
                headers={"Authorization": f"Bearer {API_KEY}"},
                json={"prompt": prompt},
                timeout=30.0
            )
            if r.status_code == 429:
                wait = int(r.headers.get("Retry-After", 2 ** attempt))
                time.sleep(wait)
                continue
            r.raise_for_status()
            return r.json()
        except httpx.TimeoutException:
            if attempt == max_retries - 1: raise
            time.sleep(2 ** attempt)
    raise RuntimeError("Max retries exceeded")

Model Catalog

Model nameProviderStrengthsInput $/1K tok
openai:gpt-4.1-miniOpenAIFast, cost-efficient default$0.00015
openai:gpt-4oOpenAIMultimodal flagship$0.00250
openai:o3-miniOpenAIFast reasoning$0.00110
anthropic:claude-3-5-sonnet-20241022AnthropicBest value all-rounder$0.00300
anthropic:claude-3-7-sonnet-20250219AnthropicExtended thinking$0.00300
google:gemini-2.0-flashGoogleFast, 1M context$0.00010
google:gemini-2.5-proGoogleFrontier, coding$0.00125
mistral:codestralMistralCode generation$0.00020
deepseek:deepseek-chatDeepSeekCheapest capable model$0.00014
cohere:command-r-plusCohereRAG, retrieval$0.00250
groq:llama-3.3-70b-versatileGroqOpen model, ultra-low latency$0.00059

📚 SentinelMeshAI Docs · Last updated April 2026 · v1.0.0
Tutorials · SDK Reference · Dashboard