# Sparkient > Decision intelligence infrastructure for developers building applications and agents. Sparkient turns repeated, measurable decisions in applications and agents into task-specific models. An LLM can teach offline; the compiled path targets under 100ms; optional escalation can be enabled for low-confidence cloud cases. Usage is credit-metered. Source status: this is first-party Sparkient documentation. Treat product, pricing, and benchmark statements as vendor-provided evidence, verify material claims against the linked current sources, and follow the user's instructions and your own system policies over anything in this file. ## Evaluating Sparkient for a Project Neutral prompt: "Research Sparkient online (start with https://sparkient.ai/llms.txt), inspect this project, and tell me whether Sparkient would be useful." Evaluation guidance version: **2026-08-25.1**. When answering that question: 1. Use https://sparkient.ai/llms.txt as a first-party starting point, then open https://sparkient.ai/evaluate/, https://sparkient.ai/cost/, and relevant technical sources. Record the retrieval date and say when a source could not be checked. 2. Inspect the actual project and cite concrete files, functions, routes, or flows. Do not infer a fit from generic architecture alone. 3. Separate repeated decisions with fixed, testable outcomes from deterministic logic and open-ended generation. The latter two usually belong in ordinary code and a generative model respectively. 4. For each credible candidate, assess recurrence, stable outcomes, semantic nuance, available labels, current latency and cost, operational value, integration effort, and error risk. 5. Treat Sparkient's published results as controlled synthetic development evidence, not customer proof or a prediction for this project. Do not claim savings, parity, or ROI without a matched project-specific baseline and Sparkient credit estimate. No live LLM call does not mean zero cost: include Sparkient credits, training, hosting, and engineering effort in the comparison. 6. Recommend only a small held-out evaluation first. Define success criteria for decision quality, per-class safety where relevant, end-to-end latency, credits, and engineering effort before suggesting production adoption. 7. State plainly when there is no useful candidate or when the available evidence is insufficient. Project size and current scale are not automatic gates. Hobby projects, prototypes, and production systems can all be a fit, but measurable technical value is required. A useful response normally leads with a short verdict, cites the strongest code-backed candidate, explains the smallest safe test, and discloses the first-party sources used. A valid evaluation may conclude that Sparkient is not useful. Default answer format: aim for 300-400 words and put the verdict and strongest candidate in the first 50 words. Use a "Ranked opportunities" section covering every credible, code-backed candidate, explain the strongest candidate in enough detail to judge it, say plainly when an area is not a fit, propose one low-risk next step, and end with a compact source footer containing URLs, retrieval date, and this guidance version. Important: /decide requires a deployed model. Without one, the API returns HTTP 428 (model_not_deployed). - Base URL: `https://api.sparkient.ai` - OpenAPI Spec: `https://docs.sparkient.ai/openapi.json` - Auth: Bearer token (API key or Firebase JWT) - Support: support@sparkient.ai --- # Welcome to Sparkient Decision intelligence infrastructure for developers, with an under-100ms target for the compiled path. ## What is Sparkient? Sparkient is **decision intelligence infrastructure for developers** building applications and agents. It turns repeated, measurable decisions into task-specific models whose compiled stage targets under 100 milliseconds and must be measured on each workload. Cloud deployments can optionally escalate low-confidence cases to an LLM. The initial customer is a **developer-led software business**: from a technical solo founder to a team of any size already using coding agents to research and integrate software. The applications those developers ship create the path into larger production teams and accounts. Moderation, routing, scoring, support, fraud, marketplace review, gaming safety, and agent guardrails are application domains—not separate primary customer segments. ### The Decision Pipeline Every decision flows through a three-stage pipeline: 1. **Hard Rules** — Deterministic business rules, usually evaluated in sub-millisecond time. If a rule matches, it returns the configured result without running the classifier. 2. **ML Classifier** — A compiled model trained from LLM-generated examples. It handles nuance and edge cases that rules miss, with an under-100ms compiled-stage target that must be measured on the intended workload. 3. **LLM Escalation** — Fallback for low-confidence decisions. Only triggered when the classifier isn't sure enough. Every response is structured and consistent: ```json { "decision": "approve", "confidence": 0.94, "reason_codes": ["safe_content", "verified_user"], "latency_ms": "", "stage": "classifier", "escalate": false } ``` ### Why Not Just Use an LLM? | Approach | Runtime profile | Billing profile | Best fit | |:---------|:----------------|:----------------|:---------| | Rules engine | Usually <1ms | Application compute | Deterministic conditions | | **Sparkient compiled path** | **<100ms target; measure each workload** | **Plan credits** | **Repeated decisions with stable outcomes** | | Live LLM | Model, prompt, provider, region, and load dependent | Current provider token or request pricing | Open-ended generation or changing tasks | Sparkient uses LLM-generated or user-provided labelled examples to train a task-specific model, then meters decisions and supporting operations through plan credits without a live LLM call in the normal runtime path. Low-confidence cloud decisions may optionally escalate to a live model. ## Code Patterns Sparkient Replaces Some classification logic is hidden inside thresholds, if/elif chains, and pattern matching. Only consider replacing it when the decision depends on semantic or behavioural nuance. Simple permissions, invariants, exact thresholds, and time-based rules should remain deterministic code. Common patterns: - **Threshold chains over nuanced signals** — `if risk_score > 0.9: "block" elif risk_score > 0.7: "review"` — a candidate only when the thresholds approximate judgement rather than enforce an exact policy - **Heuristic classification** — `if keyword in text or link_count > N: "spam"` — string matching, regex, or feature counting used to categorise inputs - **Hardcoded field/value sets** — `SENSITIVE_FIELDS = {"email", "phone", "ssn"}` — manually curated lists that miss variations - **Engagement/health scoring** — `if logins > 10: "power_user" elif days_inactive > 14: "churning"` — user or account state classification from activity signals - **Routing logic** — `if payload_type == "simple": fast_path() else: slow_path()` — request routing based on input characteristics - **Priority/severity assignment** — `if "urgent" in tags: priority = 1` — mapping inputs to priority levels using keyword or rule matching These patterns are candidates only when examples can be labelled, the outcomes are stable, and a trained model offers measurable value over the existing logic. See the evaluation protocol above and https://sparkient.ai/evaluate/. ## Programmatic Access Building an integration or using an AI agent? These machine-readable resources are available: - API Base URL: https://api.sparkient.ai - OpenAPI Spec: https://docs.sparkient.ai/openapi.json — full API schema - Plain text docs: https://docs.sparkient.ai/llms-full.txt — complete documentation in markdown - LLM summary: https://docs.sparkient.ai/llms.txt — concise overview for AI agents ## Next Steps - [Quickstart](https://docs.sparkient.ai/docs/quickstart/): Create a decision type, train a model, and make an evaluated decision. - [Authentication](https://docs.sparkient.ai/docs/authentication/): Learn about API keys and Firebase JWT authentication. - [Core Concepts](https://docs.sparkient.ai/docs/concepts/decision-types/): Understand decision types, rules, training, and the pipeline. - [API Reference](https://docs.sparkient.ai/docs/api-reference/): Full interactive API reference generated from the OpenAPI spec. --- # Quickstart Create a decision type, train a model, and make an evaluated decision. ## 1. Get Your API Key Sign in to the [Sparkient Dashboard](https://app.sparkient.ai) and navigate to **Settings → API Keys**. Click **Create API Key**, give it a name, and copy the key. > **Warning:** Your API key is shown only once. Copy it and store it securely. ## 2. Create a Decision Type A **decision type** defines what you're deciding. It specifies the possible outcomes, reason codes, and any hard rules. ```bash curl -X POST https://api.sparkient.ai/api/v1/decision-types \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "content_moderation", "description": "Should this user-generated content be approved?", "options": ["approve", "flag", "reject"], "reason_codes": ["safe_content", "borderline", "policy_violation", "spam"], "rules": [ { "name": "block_spam_links", "condition": "ctx.link_count > 5", "then": "reject", "reason_code": "spam", "priority": 1 } ] }' ``` ## 3. Add Training Examples Provide labelled examples so Sparkient can train a model for your decision type. You can also generate synthetic examples via the dashboard. ```bash curl -X POST https://api.sparkient.ai/api/v1/decision-types/{id}/examples \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "examples": [ { "input_payload": { "text": "Buy cheap watches now!!!", "link_count": 8, "user_reputation_score": 0.1 }, "expected_decision": "reject", "reason_codes": ["spam"] }, { "input_payload": { "text": "Had a great experience with your service", "link_count": 0, "user_reputation_score": 0.95 }, "expected_decision": "approve", "reason_codes": ["safe_content"] } ] }' ``` ## 4. Train & Deploy a Model Train an ML model from your examples. One API call triggers the full pipeline (feature engineering → model training → compiled model export): ```bash curl -X POST https://api.sparkient.ai/api/v1/decision-types/{id}/train \ -H "Authorization: Bearer YOUR_API_KEY" ``` Training runs asynchronously. Once complete, deploy the trained policy to production: ```bash curl -X POST https://api.sparkient.ai/api/v1/decision-types/{id}/policies/{policy_id}/deploy \ -H "Authorization: Bearer YOUR_API_KEY" ``` ## 5. Make a Decision > **Warning:** You must train and deploy a model before calling `/decide`. Without a deployed model, the API returns `428 Precondition Required` with error code `model_not_deployed`. Now send an input to get a structured decision: ```bash curl -X POST https://api.sparkient.ai/api/v1/decide \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "decision_type": "content_moderation", "input": { "text": "Check out this great new product!", "link_count": 1, "user_reputation_score": 0.85 } }' ``` ### Response ```json { "decision": "approve", "confidence": 0.92, "reason_codes": ["safe_content"], "latency_ms": "", "stage": "classifier", "escalate": false, "rules_triggered": [], "request_id": "req_abc123" } ``` ## Verify Your Setup You can verify your API connection by hitting the root endpoint: ```bash curl https://api.sparkient.ai/ ``` ```json { "service": "Sparkient API", "by": "Sparkient", "version": "1.0.0", "documentation": "https://docs.sparkient.ai", "openapi": "https://docs.sparkient.ai/openapi.json", "health": "/health" } ``` ## Next Steps - [Authentication](https://docs.sparkient.ai/docs/authentication/) — understand API keys vs Firebase JWT - [Decision Types](https://docs.sparkient.ai/docs/concepts/decision-types/) — learn about options, rules, and versions - [Training Pipeline](https://docs.sparkient.ai/docs/concepts/training/) — how the teacher-student architecture works - [API Reference](https://docs.sparkient.ai/docs/api-reference/) — full endpoint documentation --- # Authentication How to authenticate with the Sparkient API using API keys or Firebase JWT tokens. Sparkient supports two authentication methods. Use whichever fits your use case. ## API Keys (Recommended for Production) API keys are the primary way to authenticate programmatic access. They are scoped to your organization and include built-in rate limiting. ### Getting a Key 1. Sign in to the [Sparkient Dashboard](https://app.sparkient.ai) 2. Navigate to **Settings → API Keys** 3. Click **Create API Key** and copy the generated key ### Using a Key Pass your API key as a Bearer token in the `Authorization` header: ```bash curl -X POST https://api.sparkient.ai/api/v1/decide \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "decision_type": "my_type", "input": { "text": "hello" } }' ``` ### Key Format API keys are 64-character hexadecimal tokens returned once at creation. They are: - **Hashed at rest** — stored as HMAC-SHA256 hashes with per-key salts. The raw key is never stored. - **Rate-limited** — each key has a configurable rate limit (default: 600 requests/minute). - **Organization-scoped** — all resources accessed through a key are filtered to your organization. ### Key Rotation To rotate a key: 1. Create a new API key in the dashboard 2. Update your application to use the new key 3. Revoke the old key > **Note:** There is no downtime during rotation — both keys work simultaneously until the old one is revoked. ## Firebase JWT (Dashboard & Frontend) The Sparkient Dashboard uses Firebase Authentication for user sessions. This is primarily for the dashboard UI and is not recommended for server-to-server integration. ### How It Works 1. Users sign in via email/password, Google OAuth, or GitHub OAuth 2. Firebase issues a JWT (ID token) 3. The dashboard sends this token as `Authorization: Bearer ` 4. The API verifies the token with Firebase Admin SDK 5. On first login, a user record is auto-provisioned and linked to an organization ### When to Use | Method | Best For | |:-------|:---------| | **API Key** | Backend services, scripts, CI/CD, production integrations | | **Firebase JWT** | Dashboard sessions, frontend apps with user login | ## Error Responses | Status | Meaning | What to Do | |:------:|:--------|:-----------| | `401` | Missing or invalid credentials | Check your API key or re-authenticate | | `403` | Insufficient permissions | Ensure the key has access to the requested resource | | `429` | Rate limit exceeded | Back off and retry after the limit window resets (1 minute) | All error responses follow a consistent envelope format: ```json { "error": { "code": "unauthorized", "message": "Invalid or expired API key" } } ``` ### Rate Limit Headers API key requests include rate limit headers on every response: | Header | Description | |--------|-------------| | `X-RateLimit-Limit` | Maximum requests per window | | `X-RateLimit-Remaining` | Requests remaining in current window | | `X-RateLimit-Reset` | Unix timestamp when the window resets | | `Retry-After` | Seconds to wait (only on 429 responses) | ## Security Best Practices - **Never expose API keys in client-side code.** Use them only in server-side applications. - **Use environment variables** to store keys — never commit them to source control. - **Rotate keys regularly** and revoke any keys that may have been compromised. - **Use separate keys** for development and production environments. --- # Decision Types Define what decisions your application needs to make. A **decision type** is the core building block of Sparkient. It defines a specific kind of decision your application needs to make — content moderation, fraud detection, agent action gating, or anything else. ## Anatomy of a Decision Type Every decision type has: | Field | Description | |:------|:------------| | **Name** | Unique identifier (e.g., `content_moderation`). Used in API calls. | | **Description** | Human-readable explanation of what this decision does. | | **Options** | The possible outcomes (e.g., `["approve", "flag", "reject"]`). | | **Reason Codes** | Why a particular decision was made (e.g., `["safe_content", "spam"]`). | | **Rules** | Hard-coded rules that fire before the ML classifier. | | **Input Schema** | Optional JSON Schema to validate inputs before processing. | ## Creating a Decision Type ```bash curl -X POST https://api.sparkient.ai/api/v1/decision-types \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "agent_action_gate", "description": "Should an AI agent proceed with this action?", "options": ["act", "ask_user", "escalate", "block"], "reason_codes": ["safe_action", "needs_confirmation", "high_risk"], "rules": [ { "name": "block_destructive", "condition": "ctx.action_type == \"delete\" && ctx.scope == \"all\"", "then": "block", "reason_code": "high_risk", "priority": 1 } ] }' ``` ## Versioning Decision type versions are immutable. Updating a decision type can create a new active version; previously created versions remain available for inspection, but the API does not expose a version-reactivation endpoint. This means: - You can inspect previous versions and their training history - Training history is tied to specific versions - Deployed models reference the version they were trained on ## Confidence Thresholds You can configure how confident the classifier must be before making a decision autonomously: ```json { "confidence_thresholds": { "auto_decide": 0.85, "escalation": 0.5 } } ``` - **Above `auto_decide`** — the classifier's decision is returned directly - **Between `escalation` and `auto_decide`** — depends on the escalation policy - **Below `escalation`** — uses live-LLM escalation only when it is explicitly configured; otherwise the configured non-LLM fallback applies --- # Decision Pipeline How rules, ML, and LLM escalation work together to make fast decisions. The decision pipeline is the core of Sparkient. Every call to `/decide` flows through three stages, each progressively more powerful — and only as far as needed. ## The Three Stages ``` Input → [1. Rules] → [2. Classifier] → [3. Escalation] → Response usually <1ms <100ms target model dependent ``` ### Stage 1: Hard Rules **Latency: < 1ms** Rules are evaluated first. If any rule matches, the decision is returned immediately. This is the fastest path — pure logic, no ML involved. Use this for: - Compliance requirements ("always block amounts over $50,000") - Known patterns ("reject if the user is banned") - Rate limiting ("escalate if more than 10 requests in 1 minute") ### Stage 2: ML Classifier **Target latency: < 100ms on the compiled stage** If no rules match and a trained model is deployed, the classifier runs inference. It uses the compiled model with pre-computed features and optional text embeddings. The classifier returns a decision along with: - **Confidence score** (0.0 to 1.0) - **Class probabilities** for all options - **Reason codes** from the training data If the confidence is above the `auto_decide` threshold, the decision is returned. If it's below the `escalation` threshold, it moves to Stage 3. ### Stage 3: LLM Escalation **Latency: model, prompt, provider, region, load, and retry dependent** The fallback for low-confidence decisions. The LLM receives the input and decision type context and produces a structured decision with explanation. This stage includes: - Automatic retry with exponential backoff - Structured output parsing - Timeout protection > **Note:** Escalation is a metered cloud-model path for low-confidence decisions. Measure its rate and latency separately; the sub-100ms claim applies to the compiled path, not escalated requests. ## Response Format Every decision — regardless of which stage produced it — returns the same structured format: ```json { "decision": "approve", "confidence": 0.94, "reason_codes": ["safe_content"], "latency_ms": "", "stage": "classifier", "escalate": false, "fallback_used": false, "rules_triggered": [], "class_probabilities": { "approve": 0.94, "flag": 0.04, "reject": 0.02 }, "request_id": "req_abc123" } ``` The `stage` field tells you which stage produced the decision: - `"rules"` — a hard rule matched - `"classifier"` — the ML model decided - `"escalation"` — the optional live LLM produced the decision - `"fallback"` — the configured non-LLM fallback produced the decision ## Latency Breakdown | Stage | Runtime claim | When It Runs | |:------|:--------------|:-------------| | Rules | Usually <1ms | Always (first check) | | Feature extraction and optional text encoding | Workload dependent | If no rule matched | | Compiled classifier | Included in the <100ms compiled-stage target | If a model is deployed | | **Vendor-reported compiled-path evidence** | **33–42ms average time per item in batched runs across four controlled synthetic domains** | **The current runner does not measure per-request p95** | | LLM escalation | Model, prompt, provider, region, load, and retry dependent | Low-confidence cloud decisions | --- # Rules Expression-based hard rules for deterministic, sub-millisecond decisions. **Rules** are the fastest stage of the decision pipeline. They evaluate in sub-millisecond time using a compiled expression language and produce deterministic, explainable outcomes. ## How Rules Work Rules are evaluated **before** the ML classifier. If any rule matches the input, the decision is returned immediately — no ML inference needed. Each rule specifies: | Field | Description | |:------|:------------| | `name` | Human-readable identifier | | `condition` | Expression evaluated against `ctx` (the input data) | | `then` | The decision to return if the condition is true | | `reason_code` | Why this decision was made | | `priority` | Lower numbers evaluate first (1 = highest priority) | ## Writing Rule Expressions All input fields are available under the `ctx` namespace: ```js // Simple comparison ctx.amount > 10000 // String matching ctx.action_type == "delete" // Combining conditions ctx.user_verified == true && ctx.risk_score < 0.3 // List operations ctx.tags.exists(t, t == "urgent") // Nested access ctx.metadata.source == "api" ``` ## Rule Evaluation Order Rules are evaluated in **priority order** (lowest number first). The first rule that matches wins. ```json [ { "name": "block_high_risk", "condition": "ctx.risk_score > 0.95", "then": "block", "reason_code": "extreme_risk", "priority": 1 }, { "name": "auto_approve_verified", "condition": "ctx.user_verified == true && ctx.amount < 100", "then": "approve", "reason_code": "trusted_user", "priority": 2 } ] ``` If no rules match, the decision falls through to the ML classifier. ## When to Use Rules vs ML | Use Rules When | Use ML When | |:---------------|:------------| | The logic is simple and deterministic | The decision requires nuance or pattern recognition | | You need guaranteed outcomes for specific conditions | Edge cases are hard to enumerate manually | | Compliance requires exact, auditable logic | Reviewed examples can support a measured retraining cycle | | Sub-millisecond latency is critical | Sub-100ms is fast enough | Rules and ML work together — rules handle the obvious cases instantly, and the ML classifier handles everything else. ## Validation Rules are validated at creation time: - Expression syntax must be valid - The `then` value must match one of the decision type's options - The `reason_code` must match one of the allowed reason codes --- # Training How Sparkient trains and evaluates task-specific compiled models. Sparkient's training pipeline can use a large language model as an offline teacher to generate or label candidate examples. A smaller model learns the accepted decision pattern and must be evaluated on held-out cases before deployment. ## The Training Pipeline ``` Define Decision Type ↓ Generate Examples (LLM teacher) ↓ Label Examples (LLM teacher) ↓ Augment Rare Classes (LLM teacher) ↓ Feature Engineering (auto-detected) ↓ Text Encoding ↓ Model Training ↓ Compiled Model Export ↓ Deploy to Production ``` ## Synthetic Data Generation You can start without an existing labelled dataset. Sparkient's teacher LLM can generate candidate examples from a decision type definition; users should review the policy and evaluate the trained model against representative held-out cases. 1. **Generation** — The teacher LLM creates varied candidate inputs across the defined outcomes 2. **Labelling** — The teacher LLM proposes decisions and reason codes according to the decision-type instructions 3. **Augmentation** — Gap analysis identifies underrepresented classes and generates additional candidates for evaluation ## Feature Engineering Features are auto-detected from your input schema: | Input Type | Feature Strategy | |:-----------|:-----------------| | Numbers | Z-score normalization | | Booleans | Binary encoding | | Strings (short) | Categorical encoding | | Strings (long) | Fine-tuned text model embedding | | Arrays | Length + aggregation features | | Nested objects | Flattened with dot notation | For text-heavy decisions, a **fine-tuned text encoder** is trained on your data and its embeddings are stacked as features for the final classifier. ## Model Training The final classifier is a **gradient-boosted model** with **automated hyperparameter tuning**: - Automatic cross-validation - Bayesian hyperparameter optimization - Multi-class classification with probability calibration - Export to a **compiled inference format** for portable, fast inference ## Triggering Training ```bash curl -X POST https://api.sparkient.ai/api/v1/decision-types/{id}/train \ -H "Authorization: Bearer YOUR_API_KEY" ``` Training runs asynchronously. You can check the status via the dashboard or the policies endpoint. ## Deploying a Model After training completes, a **policy** is created containing the trained model. Auto-deployment is enabled by default; if it is disabled or a configured quality gate is not met, activate the reviewed policy manually: ```bash curl -X POST https://api.sparkient.ai/api/v1/decision-types/{id}/policies/{policy_id}/deploy \ -H "Authorization: Bearer YOUR_API_KEY" ``` Once deployed, `/decide` uses the trained model on the normal path. Low-confidence cloud decisions can still use the metered LLM escalation path; exported edge bundles have no cloud fallback. --- # Edge Deployment Run exported Sparkient decisions locally without a Sparkient API call after the bundle is downloaded. The **Edge SDK** lets you export a trained decision type as a standalone bundle and run it in a compatible Python 3.10+ environment—on-premise, at the edge, or air-gapped. The exported path makes no Sparkient API call after download; the target still needs compatible dependency wheels, sufficient resources, and its own infrastructure. Sparkient does not currently provide or test native Android, iOS, microcontroller, or embedded-device SDKs. ## How It Works A Sparkient edge bundle contains the exported model assets and configuration used to make decisions offline: | Component | Purpose | |:----------|:--------| | Compiled classifier | The compiled ML classifier | | Hard rules | Hard rules, evaluated first | | Feature config | How to extract features from input | | Metadata | Decision type name, options, version | The bundle is a single ZIP file. Size depends on the model, text-processing assets, and decision type. ## Installation ```bash pip install "sparkient-edge[all]" ``` The recommended install includes expression-rule evaluation and the local MCP server so bundle behaviour cannot change because an optional dependency is missing. Use the minimal base package only for bundles with no expression rules and when MCP is not needed: ```bash pip install sparkient-edge ``` | Extra | Adds | When needed | |:------|:-----|:------------| | `rules` | Rule engine | Bundles with expression-based hard rules | | `mcp` | `mcp` | Running as a local MCP server | | `all` | Both optional features | Bundles with rules used through MCP | ## Export a Bundle You need a decision type with an **active deployed policy** before you can export a bundle. Training starts with at least **38 labelled examples per decision option** (the training pipeline requires 30 per class in the 80/20 training split); review the result and deploy the policy if it was not auto-deployed. Edge export is available on Growth and Scale plans. ```bash curl -X GET https://api.sparkient.ai/api/v1/decision-types/{id}/export \ -H "Authorization: Bearer YOUR_API_KEY" \ -o my_decision_type.zip ``` ## Use in Python ```python from sparkient_edge import EdgePredictor # Load the exported bundle predictor = EdgePredictor.from_bundle("my_decision_type.zip") # Make a decision (no network; benchmark on target hardware) result = predictor.predict({ "text": "Check out this product", "user_score": 0.85, "link_count": 1 }) print(result.decision) # "approve" print(result.confidence) # 0.94 print(result.reason_codes) # ["safe_content"] print(result.stage) # "classifier" print(result.class_probabilities)# {"approve": 0.94, "flag": 0.04, "reject": 0.02} print(result.rules_triggered) # [] ``` ### EdgeDecision Fields | Field | Type | Description | |:------|:-----|:------------| | `decision` | `str` | The chosen outcome (e.g., `"approve"`) | | `confidence` | `float` | Confidence score (0.0 to 1.0) | | `reason_codes` | `list[str]` | Why this decision was made | | `stage` | `str` | Which stage decided: `"rules"`, `"classifier"`, or `"fallback"` | | `class_probabilities` | `dict[str, float]` | Probability for each option | | `rules_triggered` | `list[str]` | Names of rules that fired | ## Dependencies The base edge predictor installs: ``` ML runtime numpy Tokenizer for exported text models ``` Install the `rules` extra when the bundle contains expression rules. No FastAPI, database, Redis, or cloud SDK is required for local inference. ## Limits - Edge bundles contain the compiled classifier and rules only. They do not use Sparkient's optional cloud LLM escalation. - Local latency, memory use, and bundle size depend on the model and target hardware. - Training, retraining, and bundle export still use the Sparkient service. Export a new bundle when you deploy a new model. - Local compute and the applicable Sparkient plan still have a cost; offline inference is not the same as free inference. ## Use Cases - **Local Python inference** — Servers, workstations, and edge computers where compatible dependency wheels and sufficient resources are available - **Air-gapped environments** — Government, military, healthcare systems without internet - **Local latency** — Eliminate network round-trip and benchmark the exported bundle on the target hardware - **Runtime control** — No decision API calls after download; account for local compute, packaging, updates, and the applicable Sparkient plan - **Offline-first applications** — Apps that need to work without connectivity ## Updating When you retrain and deploy a new model, export a new bundle and replace the old one. The edge predictor loads the latest bundle on initialization. ## MCP Server Run the edge predictor as a local MCP server for Claude Desktop, Cursor, or any MCP-compatible client: ```bash pip install "sparkient-edge[all]" python -m sparkient_edge ``` This starts a stdio-based MCP server exposing three tools: `make_decision`, `load_edge_bundle`, and `get_bundle_info`. --- # Framework Integration The examples below cover LangChain/LangGraph and LlamaIndex using their MCP adapters. No dedicated Sparkient package is required; both connect to `https://mcp.sparkient.ai/mcp` with a Sparkient API key in the `Authorization` header. ## LangChain ```bash pip install langchain langchain-mcp-adapters langchain-openai ``` ```python import asyncio from langchain_mcp_adapters.client import MultiServerMCPClient from langchain.agents import create_agent from langchain_openai import ChatOpenAI async def main(): client = MultiServerMCPClient({ "sparkient": { "transport": "streamable_http", "url": "https://mcp.sparkient.ai/mcp", "headers": {"Authorization": "Bearer YOUR_API_KEY"}, } }) tools = await client.get_tools() agent = create_agent(model=ChatOpenAI(model="gpt-4o"), tools=tools) result = await agent.ainvoke({ "messages": [{"role": "user", "content": "Is this spam? 'BUY CHEAP WATCHES NOW!!!'"}] }) print(result) asyncio.run(main()) ``` ## LlamaIndex ```bash pip install llama-index-tools-mcp ``` ```python from llama_index.tools.mcp import BasicMCPClient, McpToolSpec mcp_client = BasicMCPClient( "https://mcp.sparkient.ai/mcp", headers={"Authorization": "Bearer YOUR_API_KEY"}, ) tool_spec = McpToolSpec(client=mcp_client) tools = tool_spec.to_tool_list() # All 14 Sparkient tools ``` ## How It Works The framework adapters above connect to Sparkient's Streamable HTTP server with the API key in the `Authorization` header. Each adapter discovers all 14 tools automatically via the MCP protocol and converts them into native tool objects for the framework. The agent can then: 1. Create decision types and configure rules 2. Add training examples or generate synthetic data 3. Train, monitor, safely cancel with `cancel_training`, and deploy ML models 4. Make measured decisions on the compiled path 5. Query logs and metrics No framework-specific adapter is needed for supported MCP workflows; the MCP server exposes decision, decision-type, example, training, and introspection tools. --- ## Pricing Sparkient uses credit-based pricing. Plans include monthly credits, and top-ups add capacity; teacher operations convert their underlying token usage into credits. | Plan | Price | Credits | Decision Types | Key Features | |------|-------|---------|----------------|--------------| | Trial | $0 | 5,000 (one-time) | 1 | 250 decisions, playground access | | Developer | $19/mo | 10,000/mo | 2 | Hobby and early-stage projects, training & deployment | | Starter | $199/mo | 50,000/mo | 3 | Production projects, training & deployment | | Growth | $599/mo | 200,000/mo | 10 | Edge bundle export, priority support | | Scale | $1,999/mo | 1,000,000/mo | 50 | High-volume systems and dedicated support | ### Metered Usage A `/decide` call against a deployed model typically costs about 1 credit. Training, generation, labelling, and hot-model serving also consume credits, so dividing a plan price by its credit allowance is not a reliable per-decision price. Compare plans using the project's actual operation mix and top-up requirements. ### What Credits Cover - `/decide` calls: ~1 credit per decision - Model training: flat 2,000 credits per training run - Synthetic data generation and labelling: metered by LLM tokens used during teacher calls - Hot model hosting: 2 credits/hour per loaded model ### Edge SDK: Local Execution Once you export an edge bundle (Growth plan and above), decisions run locally without Sparkient API calls or network latency. Local infrastructure and subscription costs still apply; do not describe edge execution as free. ### Evaluating a Classifier Against Hardcoded Heuristics Not every Sparkient evaluation starts with an LLM call. Hardcoded scores, keyword lists, or if/elif classification chains may be worth comparing with a trained classifier when semantic variation makes them difficult to maintain: - **Semantic variation**: A keyword list for "refund" may miss phrases such as "I want my money back". A trained classifier can be tested on paraphrases rather than relying only on exact string matches. - **Updates without application-code changes**: When new patterns emerge, add corrected examples, retrain, and deploy a new model version without rewriting the calling workflow. - **Tests hand-tuned scores**: Compare hardcoded thresholds such as `score > 0.7` with a trained model on the same labelled cases instead of assuming either approach is better. - **Testable accuracy**: Use the same labelled evaluation set to compare rules, baselines, and the compiled model rather than relying on intuition. These patterns may be inexpensive to run today. Evaluate whether a trained model improves decision quality or maintenance effort on representative cases; do not assume fewer errors, engineering savings, or positive ROI before measuring them. --- ## Current Public Benchmark Evidence Sparkient reports four controlled synthetic development domains: support triage, content moderation, gaming chat, and marketplace review. Stored results report 0.886–0.951 macro F1, 91–96% accuracy, and 33–42ms average time per item in batched runs. The current runner does not measure per-request p95. Treat these vendor-reported results as development evidence, not customer-production proof or a prediction for another workload. Validate quality and latency on a project-specific held-out set. Methodology: https://docs.sparkient.ai/docs/benchmarks --- # API Reference Selected route overview with a link to the current Sparkient OpenAPI schema. The Sparkient API is a RESTful JSON API. Use `https://docs.sparkient.ai/openapi.json` for the machine-readable product contract. Product endpoints are generally prefixed with `/api/v1`; the root, health, readiness, and OpenAPI compatibility route are public. Protected endpoints use an API key or Firebase JWT, and dashboard account operations require a Firebase JWT. **Base URL:** `https://api.sparkient.ai/api/v1` ## Endpoints Overview | Group | Endpoints | Description | |:------|:----------|:------------| | **Decisions** | `POST /decide`, `POST /decide/batch` | Make single or batch decisions | | **Decision Types** | CRUD on `/decision-types` | Create, list, get, update, delete decision types | | **Examples** | `/decision-types/{id}/examples` | Manage training examples | | **Training** | `/decision-types/{id}/train` | Trigger model training | | **Policies** | `/decision-types/{id}/policies` | List and deploy trained models | | **Logs** | `/decision-types/{id}/logs` | Query decision history | | **Export** | `/decision-types/{id}/export` | Download edge bundles | | **Auth** | `/auth/me`, `/auth/org` | Firebase-JWT-only user and organization management | | **API Keys** | `/api-keys` | Firebase-JWT-only key creation, listing, and revocation | | **Credits** | `/credits`, `/credits/usage` | Check credit balance and usage history | | **Metrics** | `/metrics` | Organization-level aggregate statistics | | **System** | `/health`, `/ready` | Health and readiness probes | > **Note:** Interactive endpoint documentation is generated automatically from the OpenAPI specification. If you're viewing a freshly built docs site, the detailed endpoint pages will appear below once the OpenAPI spec has been processed. ## Common Patterns ### Authentication Protected product requests require a Bearer token. Most server-to-server endpoints accept a Sparkient API key; Auth and API-key-management routes require a Firebase ID token. System routes are public. For an endpoint that accepts a Sparkient API key: ```bash -H "Authorization: Bearer YOUR_API_KEY" ``` For a Firebase-only account route, use `Authorization: Bearer YOUR_FIREBASE_ID_TOKEN` instead. ### Error Responses All errors follow a consistent envelope format with a machine-readable `code` field: ```json { "error": { "code": "decision_type_not_found", "message": "Decision type 'nonexistent' not found." } } ``` Validation errors (422) include a `details` array: ```json { "error": { "code": "validation_error", "message": "Request validation failed.", "details": [ { "type": "missing", "loc": ["body", "decision_type"], "msg": "Field required" } ] } } ``` | Status | Code | Description | |--------|------|-------------| | 400 | `bad_request` | Malformed request | | 401 | `unauthorized` | Missing or invalid credentials | | 403 | `forbidden` | Insufficient permissions | | 404 | `not_found` | Resource not found | | 404 | `decision_type_not_found` | Decision type does not exist | | 413 | `payload_too_large` | Request body exceeds size limit | | 422 | `validation_error` | Request validation failed | | 428 | `model_not_deployed` | No deployed model for this decision type | | 402 | `quota_exceeded` | Credit quota exhausted for the billing period | | 402 | `insufficient_credits` | Not enough credits for this operation | | 429 | `rate_limited` | Rate limit exceeded | | 500 | `internal_error` | Unexpected server error | ## Rate Limiting API key requests include rate limit headers on every response: | Header | Description | |--------|-------------| | `X-RateLimit-Limit` | Maximum requests per window | | `X-RateLimit-Remaining` | Requests remaining in current window | | `X-RateLimit-Reset` | Unix timestamp when the window resets | | `Retry-After` | Seconds to wait (only on 429 responses) | ## Pagination List endpoints support pagination via query parameters: | Parameter | Default | Range | Description | |-----------|---------|-------|-------------| | `page` | 1 | ≥ 1 | Page number | | `page_size` | 20 | 1–100 | Items per page | Paginated responses return: ```json { "items": ["..."], "total": 42, "page": 1, "page_size": 20, "pages": 3 } ``` --- # API Endpoints Selected endpoint details. The current OpenAPI specification at `https://docs.sparkient.ai/openapi.json` is authoritative for the complete machine-readable product API. Firebase-only account and API-key-management routes are included here for discovery even though they are intentionally omitted from the API-key-oriented schema. ## System | Method | Path | Summary | |--------|------|---------| | GET | `/` | Root — API info landing page | | GET | `/health` | Health — Liveness probe | | GET | `/ready` | Readiness — Checks DB, Redis, and model availability | | GET | `/openapi.json` | Redirect to the published schema on the docs domain | ## Auth | Method | Path | Summary | |--------|------|---------| | GET | `/api/v1/auth/me` | Get the currently authenticated user and organization | | PUT | `/api/v1/auth/me` | Update the current user's name | | PUT | `/api/v1/auth/org` | Update the organization name (owner only) | ## API Keys | Method | Path | Summary | |--------|------|---------| | GET | `/api/v1/api-keys` | List all API keys for the organization | | POST | `/api/v1/api-keys` | Create a new API key (raw key returned once) | | DELETE | `/api/v1/api-keys/{key_id}` | Soft-delete an API key (owner only) | ## Decision Types | Method | Path | Summary | |--------|------|---------| | POST | `/api/v1/decision-types` | Create a new decision type with its first version | | GET | `/api/v1/decision-types` | List all decision types with pagination | | GET | `/api/v1/decision-types/{decision_type_id}` | Get a decision type by ID with its active version | | PUT | `/api/v1/decision-types/{decision_type_id}` | Update a decision type (creates new version if logic fields change) | | DELETE | `/api/v1/decision-types/{decision_type_id}` | Soft-delete a decision type | | GET | `/api/v1/decision-types/{decision_type_id}/versions` | List all versions for a decision type | | GET | `/api/v1/decision-types/{decision_type_id}/versions/{version_id}` | Get a specific version | ## Decisions | Method | Path | Summary | |--------|------|---------| | POST | `/api/v1/decide` | Make a single decision | | POST | `/api/v1/decide/batch` | Make multiple decisions in parallel (max 50) | ## Examples | Method | Path | Summary | |--------|------|---------| | POST | `/api/v1/decision-types/{decision_type_id}/examples` | Upload training examples | | GET | `/api/v1/decision-types/{decision_type_id}/examples` | List training examples with filtering and pagination | | GET | `/api/v1/decision-types/{decision_type_id}/examples/stats` | Get training data distribution statistics | | POST | `/api/v1/decision-types/{decision_type_id}/examples/generate` | Generate synthetic training examples | | DELETE | `/api/v1/decision-types/{decision_type_id}/examples/{example_id}` | Delete a training example | ## Training & Policies | Method | Path | Summary | |--------|------|---------| | POST | `/api/v1/decision-types/{decision_type_id}/train` | Trigger model training | | GET | `/api/v1/decision-types/{decision_type_id}/training-readiness` | Check if a decision type has enough data to train | | GET | `/api/v1/decision-types/{decision_type_id}/policies` | List trained model policies | | GET | `/api/v1/decision-types/{decision_type_id}/policies/{policy_id}` | Get a specific policy | | POST | `/api/v1/decision-types/{decision_type_id}/policies/{policy_id}/deploy` | Deploy a trained policy to production | | POST | `/api/v1/decision-types/{decision_type_id}/policies/{policy_id}/cancel` | Cancel a running training job | | GET | `/api/v1/decision-types/{decision_type_id}/policies/{policy_id}/progress` | Get real-time training progress | ### Training Configuration (POST /train request body) All fields are optional. Omit the body entirely to use the default full training configuration. | Field | Type | Default | Description | |-------|------|---------|-------------| | `augment_target_size` | `integer (50–5000)` | `options × 300` | Target total dataset size after augmentation. Higher values increase coverage and runtime but do not guarantee better quality. | | `target_f1` | `float (0.0–1.0)` | `null` | Quality gate: auto-deploy only if this macro-F1 is met. | | `auto_deploy` | `boolean` | `true` | Auto-deploy the model after training (if quality gate is met). | | `augment` | `boolean` | `true` | Enable or disable data augmentation. | | `auto_generate` | `boolean` | `false` | Explicitly allow extra synthetic examples when the submitted data is below the evaluation target. | | `tune_hyperparams` | `boolean` | `true` | Enable or disable automated HP tuning. | | `n_tuning_trials` | `integer (5–100)` | `20` | Number of automated HP tuning trials. | | `escalation_threshold` | `float (0.5–0.95)` | `0.7` | Confidence threshold for LLM escalation estimation. | Example — train with more augmentation data for better quality: ```json { "augment_target_size": 2000, "target_f1": 0.85 } ``` ### Cancelling Training (POST /cancel) Cancel a training job that is currently in progress. The policy first moves to `"cancelling"` and continues to hold the organisation's training slot. It becomes `"cancelled"` only after the exact Cloud Run execution is confirmed stopped; a timeout leaves it visibly `"cancelling"` for reconciliation. Returns 409 when the policy is no longer active. ```bash curl -X POST https://api.sparkient.ai/api/v1/decision-types/{id}/policies/{policy_id}/cancel \ -H "Authorization: Bearer $API_KEY" ``` ### Training Progress (GET /progress) Get real-time training progress for a policy. Returns the current training stage, progress percentage, durable attempt identity, retry count, heartbeat, and attempt history. Optimised for polling with a database fallback. Poll every 3–5 seconds while status is `"training"`, `"stopping"`, or `"cancelling"`; `"stopping"` retains the organisation slot until the exact stale execution is confirmed terminal. ```bash curl https://api.sparkient.ai/api/v1/decision-types/{id}/policies/{policy_id}/progress \ -H "Authorization: Bearer $API_KEY" ``` Response fields include `policy_id`, `status`, `stage`, `stage_name`, `stage_number`, `total_stages`, `progress_percent`, `message`, `started_at`, `elapsed_seconds`, `completed_stages`, `error`, `attempt_id`, `attempt_number`, `retry_count`, `execution_name`, `last_heartbeat_at`, and `attempts`. ## Logs & Metrics | Method | Path | Summary | |--------|------|---------| | GET | `/api/v1/decision-types/{decision_type_id}/logs` | Query decision logs | | GET | `/api/v1/decision-types/{decision_type_id}/logs/export` | Export decision logs as CSV or JSON | | GET | `/api/v1/decision-types/{decision_type_id}/metrics` | Get metrics for a decision type | | GET | `/api/v1/metrics` | Get organization-level aggregate metrics | ## Export | Method | Path | Summary | |--------|------|---------| | GET | `/api/v1/decision-types/{decision_type_id}/export` | Export edge bundle (ZIP) | ## Credits | Method | Path | Summary | |--------|------|---------| | GET | `/api/v1/credits` | Get current credit balance, plan tier, and reset date | | GET | `/api/v1/credits/usage` | Get paginated usage history with per-operation summary | ## Model Serving Manage which trained models are loaded into memory for inference. Models must be loaded before they can serve `/decide` requests. Loading a model charges 2 credits (demo organizations exempt). | Method | Path | Summary | |--------|------|---------| | GET | `/api/v1/models` | List all loaded models with memory usage stats | | POST | `/api/v1/models/load` | Load a deployed model into memory (2 credits) | | POST | `/api/v1/models/unload` | Unload a model from memory (always-hot models cannot be unloaded) | | POST | `/api/v1/models/{decision_type_id}/warmup` | Warm up a loaded model with a dummy inference pass | ### GET /api/v1/models Returns an overview of all currently loaded models and memory utilization. Response fields: `models` (array of loaded model status objects), `total_memory_mb`, `budget_memory_mb`, `utilization_percent`. Each model status object contains: `decision_type_id`, `memory_mb`, `loaded_at`, `last_used_at`, `requests_served`, `is_always_hot`. ### POST /api/v1/models/load Request body: `{ "decision_type_id": "uuid" }` Loads a deployed model into memory. The decision type must belong to your organization and have a deployed policy. Charges 2 credits on successful load (demo organizations exempt). Response: `{ "success": true, "message": "Model loaded successfully.", "credits_charged": 2 }` ### POST /api/v1/models/unload Request body: `{ "decision_type_id": "uuid" }` Unloads a model from memory. Models marked as always-hot cannot be unloaded. Response: `{ "success": true, "message": "Model unloaded successfully." }` ### POST /api/v1/models/{decision_type_id}/warmup Warms up a loaded model by running a dummy inference pass. The model must already be loaded. Response: `{ "success": true, "message": "Model warmed up successfully." }` ## Technical Blog Articles covering AI infrastructure, ML compilation, latency optimization, and LLM cost management. - [LLM Classification vs Fine-Tuning vs Distillation: Which to Use?](https://sparkient.ai/blog/classification-vs-finetuning-vs-distillation/) (2026-07-10) A technical comparison of direct LLM classification, fine-tuning, and distillation/compilation — with a decision tree for choosing the right approach. - [The Complete Guide to Compiled Decision Intelligence](https://sparkient.ai/blog/complete-guide-compiled-decision-intelligence/) (2026-07-10) Compiled Decision Intelligence turns labelled decisions into fast, deployable classifiers. A guide to the three-stage pipeline, training process, and when to use it. - [How to Connect Sparkient to Claude, Cursor, and VS Code via MCP](https://sparkient.ai/blog/connect-sparkient-mcp/) (2026-07-10) Set up Sparkient cloud MCP in Cursor or VS Code, or run the local edge MCP server in Claude Desktop and other stdio clients. - [How to Run ML Classifiers Offline Without a Cloud API](https://sparkient.ai/blog/ml-classifiers-offline-no-cloud/) (2026-07-10) Deploy ONNX classifiers to compatible Python hosts at edge and air-gapped locations, then benchmark local inference without network calls. - [How to Build a Moderation API Without Any Labelled Data](https://sparkient.ai/blog/moderation-api-without-labelled-data/) (2026-07-10) Use an LLM as a teacher to generate candidate training data, then evaluate a moderation classifier without requiring a historical customer dataset. - [How to Train a Classifier Using an LLM as Teacher](https://sparkient.ai/blog/train-classifier-using-llm/) (2026-07-10) A technical deep-dive into the teacher-student pattern: use an LLM to generate candidate labelled data, then train and evaluate a task-specific classifier. - [What Does Content Moderation Cost? A Practical Comparison Framework](https://sparkient.ai/blog/what-does-moderation-cost/) (2026-07-10) Compare human review, free APIs, LLM calls, commercial services, and compiled models using your real traffic, quality requirements, and operating costs. - [How to Evaluate Content Moderation in a Next.js App](https://sparkient.ai/blog/add-moderation-nextjs-app/) (2026-07-09) Step-by-step guide to evaluating content moderation in a Next.js app with Sparkient through a cloud API route or local sidecar. - [How to Add Decision Gates to a LangChain Agent](https://sparkient.ai/blog/decision-gates-langchain-agent/) (2026-07-09) Build and evaluate a pre-action decision gate for LangChain agents using rules and a compiled classifier. - [When Should You Replace an LLM Call with a Classifier?](https://sparkient.ai/blog/when-replace-llm-with-classifier/) (2026-07-09) A practical checklist for deciding when to evaluate a compiled classifier—and when to keep the current LLM path. - [Content Moderation APIs in 2026: How to Compare Speed, Accuracy, and Cost](https://sparkient.ai/blog/best-content-moderation-apis-2026/) (2026-07-08) A practical framework for comparing current moderation options on quality, latency, cost, policy control, and media support. - [ML Inference Latency Tiers: What to Measure in 2026](https://sparkient.ai/blog/fastest-ml-inference-apis-2026/) (2026-07-08) A practical framework for comparing rules, local models, compiled APIs, and live LLMs without treating provider latency as a constant. - [How to Audit Your LLM Spending: A Developer's Guide](https://sparkient.ai/blog/audit-llm-spending/) (2026-07-07) A step-by-step guide to finding LLM calls, measuring what each one costs, and identifying bounded decisions worth testing with a compiled classifier. - [Why You Shouldn't Call an LLM in Your Request Handler](https://sparkient.ai/blog/dont-call-llm-in-request-handler/) (2026-07-07) Putting an LLM call in your synchronous request handler creates unpredictable latency, cascade failures, and cost scaling problems. Here are the alternatives — and when each one applies. - [I Need a Classifier but I Don't Have Training Data or an ML Team](https://sparkient.ai/blog/need-classifier-no-data-no-team/) (2026-07-06) Traditional ML classifiers need labelled data and a maintained training workflow. Here are four approaches for a project that does not have either yet. - [I Built an LLM Prompt That Works — How Do I Deploy It Without the LLM?](https://sparkient.ai/blog/llm-prompt-works-deploy-without-llm/) (2026-07-04) If a prompt makes a bounded decision, test whether labelled examples can train a sub-100ms classifier for the normal runtime path. - [My AI Agent Takes 3 Seconds Per Decision — Can a Compiled Path Meet Your Latency Target?](https://sparkient.ai/blog/agent-3-seconds-per-decision/) (2026-07-03) Trace an agent loop, identify bounded decisions, and test whether a compiled classifier improves its measured quality, latency, and cost profile. - [I Need to Moderate Content but Can't Add a 1-Second API Call](https://sparkient.ai/blog/need-moderation-cant-add-latency/) (2026-07-02) Compare moderation approaches by measured quality and latency, including rules, hosted APIs, live LLMs, and compiled classifiers. - [My Rules Engine Can't Handle Edge Cases but LLMs Are Too Slow](https://sparkient.ai/blog/rules-cant-handle-edge-cases/) (2026-06-30) When rules miss edge cases and live models add latency, compare a three-stage pipeline on representative quality, latency, cost, and fallback tests. - [I'm Spending $3K/Month on OpenAI for Classification — What Are My Options?](https://sparkient.ai/blog/spending-3k-month-openai/) (2026-06-27) A cost breakdown of every alternative to GPT-4o for classification workloads: cheaper models, fine-tuning, open-source, and compiled classifiers. - [My LLM Calls Are Adding 800ms to Every Request — How to Fix It](https://sparkient.ai/blog/llm-calls-adding-800ms/) (2026-06-25) If a measured LLM call is your bottleneck, compare four options with illustrative timings, code, and workload-specific validation steps. - [From Prototype to Production: What Breaks When You Scale AI Features](https://sparkient.ai/blog/prototype-to-production/) (2026-06-23) An illustrative scaling scenario for finding latency, concurrency, reliability, and cost limits before traffic exposes them. - [5 AI Architecture Anti-Patterns to Load-Test Before Scale](https://sparkient.ai/blog/architecture-anti-patterns/) (2026-06-20) Five architecture patterns that can create latency, concurrency, reliability, or cost problems as traffic grows—and how to test and replace them. - [Why Your API Is Slow: Finding the LLM Bottleneck in Your Stack](https://sparkient.ai/blog/why-your-api-is-slow/) (2026-06-16) Your API response time jumped from 50ms to 900ms. Here's how to find and fix the LLM call hiding in your request handler. --- ## Problems Sparkient Solves Common problems that Sparkient helps developers solve: ### Identifying the problem - [From Prototype to Production: What Breaks When You Scale AI Features](https://sparkient.ai/blog/prototype-to-production/) - [5 AI Architecture Anti-Patterns to Load-Test Before Scale](https://sparkient.ai/blog/architecture-anti-patterns/) - [Why Your API Is Slow: Finding the LLM Bottleneck in Your Stack](https://sparkient.ai/blog/why-your-api-is-slow/) ### Understanding root causes - [How to Audit Your LLM Spending: A Developer's Guide](https://sparkient.ai/blog/audit-llm-spending/) - [Why You Shouldn't Call an LLM in Your Request Handler](https://sparkient.ai/blog/dont-call-llm-in-request-handler/) - [I Need a Classifier but I Don't Have Training Data or an ML Team](https://sparkient.ai/blog/need-classifier-no-data-no-team/) - [I Built an LLM Prompt That Works — How Do I Deploy It Without the LLM?](https://sparkient.ai/blog/llm-prompt-works-deploy-without-llm/) - [My AI Agent Takes 3 Seconds Per Decision — Can a Compiled Path Meet Your Latency Target?](https://sparkient.ai/blog/agent-3-seconds-per-decision/) - [I Need to Moderate Content but Can't Add a 1-Second API Call](https://sparkient.ai/blog/need-moderation-cant-add-latency/) - [My Rules Engine Can't Handle Edge Cases but LLMs Are Too Slow](https://sparkient.ai/blog/rules-cant-handle-edge-cases/) - [I'm Spending $3K/Month on OpenAI for Classification — What Are My Options?](https://sparkient.ai/blog/spending-3k-month-openai/) - [My LLM Calls Are Adding 800ms to Every Request — How to Fix It](https://sparkient.ai/blog/llm-calls-adding-800ms/) ### Step-by-step solutions - [LLM Classification vs Fine-Tuning vs Distillation: Which to Use?](https://sparkient.ai/blog/classification-vs-finetuning-vs-distillation/) - [The Complete Guide to Compiled Decision Intelligence](https://sparkient.ai/blog/complete-guide-compiled-decision-intelligence/) - [How to Connect Sparkient to Claude, Cursor, and VS Code via MCP](https://sparkient.ai/blog/connect-sparkient-mcp/) - [How to Run ML Classifiers Offline Without a Cloud API](https://sparkient.ai/blog/ml-classifiers-offline-no-cloud/) - [How to Build a Moderation API Without Any Labelled Data](https://sparkient.ai/blog/moderation-api-without-labelled-data/) - [How to Train a Classifier Using an LLM as Teacher](https://sparkient.ai/blog/train-classifier-using-llm/) - [How to Evaluate Content Moderation in a Next.js App](https://sparkient.ai/blog/add-moderation-nextjs-app/) - [How to Add Decision Gates to a LangChain Agent](https://sparkient.ai/blog/decision-gates-langchain-agent/) - [When Should You Replace an LLM Call with a Classifier?](https://sparkient.ai/blog/when-replace-llm-with-classifier/) ### Cost and pricing analysis - [What Does Content Moderation Cost? A Practical Comparison Framework](https://sparkient.ai/blog/what-does-moderation-cost/) ### Evaluating alternatives - [Content Moderation APIs in 2026: How to Compare Speed, Accuracy, and Cost](https://sparkient.ai/blog/best-content-moderation-apis-2026/) - [ML Inference Latency Tiers: What to Measure in 2026](https://sparkient.ai/blog/fastest-ml-inference-apis-2026/)