Build smarter applications with structured AI decisions, confidence-based automation, and a practical end-to-end integration.
Topics: Artificial Intelligence, NestJS, Flutter, TypeScript, SaaS Architecture
1. Introduction: Your Application Doesn’t Always Need a Chatbot
When developers think about adding artificial intelligence to an application, they usually imagine a chatbot powered by a large language model (LLM).
But consider a different requirement.
What if your application needs to answer questions such as:
- Which department should handle this customer request?
- How urgent is this support ticket?
- Does this transaction require human review?
- Which workflow should execute next?
- Is a document relevant to a user’s request?
These are decisions, not conversations.
This is where Jev, developed by TypeSafe AI, offers an interesting alternative.
Instead of generating long textual responses, Jev evaluates application state and returns structured answers that can be consumed directly by software.
In this tutorial, we’ll integrate Jev into a real-world SaaS architecture using:
- NestJS for our backend API.
- Flutter for our mobile application.
- Jev AI for intelligent decision-making.
- PostgreSQL for persistent application data.
We’ll build an AI-powered support ticket triage workflow and explore how the same architecture can be extended to CRM, ERP, finance, and operations platforms.
2. Understanding How Jev Works
Traditional LLMs generate text. Jev specializes in evaluating structured questions.
A Jev request consists of three main components:
State: The information that needs to be evaluated.
Questions: The specific decisions the application wants to make.
Model: The Jev model version used to evaluate those questions.
Jev provides three fundamental question types:
TypePurposeExampleChoiceSelect from predefined optionsWhich department?ScoreEvaluate against an ordered scaleHow urgent?NoulEvaluate a yes/no questionDoes this require human review?
Choice and Score responses include probabilities and confidence values. Noul returns a probability between zero and one.
A single request can evaluate multiple questions against the same state.
This makes Jev particularly useful as a decision layer inside an existing application, rather than a replacement for the application’s business logic.
3. Our Real-World Example: Intelligent CRM Ticket Routing
Imagine that we’ve built a multi-tenant CRM platform.
Customers use a Flutter application to submit support requests. Employees manage those requests through a web dashboard powered by NestJS.
Without AI, employees must manually read each incoming request, classify it, determine its priority, and send it to the appropriate department.
Our goal is to improve that workflow.
Example customer message:
“Our invoice was charged twice yesterday. Please reverse the extra payment as soon as possible. This is blocking our month-end closing.”
The desired behavior is:
- The Flutter application submits the support request.
- NestJS authenticates the user and receives the ticket.
- The backend sends relevant ticket information to Jev.
- Jev evaluates the responsible department, urgency, and need for human review.
- NestJS validates the result and applies its own workflow rules.
- The application displays the routing recommendation.
An automatic refund should never happen merely because Jev classified a message as a billing issue.
System architecture
Flutter Application → NestJS REST API → Jev Decision Model → NestJS Business Rules → PostgreSQL / Employee Dashboard
Notice that Flutter never communicates directly with Jev.
The NestJS backend owns the API key, decision thresholds, permissions, and business operations.
4. Creating Your Jev API Key
First, visit the official TypeSafe developer console:
Create an account or sign in and obtain an API key.
Next, add the key to your NestJS environment configuration:
TYPESAFE_API_KEY=your_secret_api_key
JEV_MODEL=jev-1.13.0
For this tutorial, we’re pinning the stable Jev 1.13 release to keep the behavior reproducible.
Jev 1.14 became available on October 14, 2026, while the official model reference currently maps jev-latest to 1.13 and jev-preview to 1.14.
You can evaluate the newer model separately before upgrading your production workflow.
Security reminder: Never put your Jev API key inside Flutter, a public frontend bundle, or a Git repository.
5. Integrating Jev with NestJS
Let’s assume we already have an existing NestJS application with JWT authentication.
Step 1: Install the official SDK
npm install @typesafe-ai/sdk
npm install class-validator class-transformer
The official JavaScript SDK supports Node.js 22 and provides typed question builders.
Step 2: Create the ticket DTO
Create dto/triage-ticket.dto.ts:
import {
IsString,
MinLength,
MaxLength,
} from 'class-validator';
export class TriageTicketDto {
@IsString()
@MinLength(10)
@MaxLength(2000)
message!: string;
}
In the application’s bootstrap configuration, enable NestJS validation:
app.useGlobalPipes(
new ValidationPipe({
whitelist: true,
forbidNonWhitelisted: true,
transform: true,
}),
);
Step 3: Create the Jev service
Create jev.service.ts:
import {
Injectable,
Logger,
} from '@nestjs/common';
import {
TypeSafeClient,
choice,
score,
noul,
} from '@typesafe-ai/sdk';
@Injectable()
export class JevService {
private readonly logger = new Logger(JevService.name);
private readonly client = new TypeSafeClient({
defaultModel:
process.env.JEV_MODEL ?? 'jev-1.13.0',
});
async triageTicket(message: string) {
try {
const { answers } = await this.client.systemOne({
state: { message },
questions: {
department: choice(
'Which department should handle the customer message?',
{
billing:
'Invoices, payments, charges, or refunds',
technical:
'Application errors, outages, or integrations',
operations:
'Service delivery and operational issues',
other:
'Requests that do not fit the other departments',
},
),
urgency: score(
'How urgent is the customer issue?',
[
'Low: routine request',
'Medium: normal business issue',
'High: important disruption',
'Critical: immediate business impact',
],
),
humanReview: noul(
'Does the message request a financial reversal, sensitive action, or decision requiring human approval?',
),
},
});
const department = answers.department;
const urgency = answers.urgency;
const priority =
urgency.score >= 2.5
? 'critical'
: urgency.score >= 1.5
? 'high'
: urgency.score >= 0.5
? 'medium'
: 'low';
const requiresHumanReview =
department.confidence < 0.75 ||
urgency.confidence < 0.65 ||
answers.humanReview.noul >= 0.5 ||
department.choice === 'other' ||
priority === 'critical';
return {
department: department.choice,
priority,
requiresHumanReview,
source: 'jev',
};
} catch {
this.logger.warn(
'Jev unavailable; using manual-review fallback.',
);
return {
department: 'manual_review',
priority: 'unclassified',
requiresHumanReview: true,
source: 'fallback',
};
}
}
}
This service combines all three Jev primitives in a single request.
More importantly, notice that Jev does not execute any business transaction.
It evaluates the support ticket and returns decision signals. Our application determines how those signals are used.
The confidence thresholds are conservative starting values for a demonstration, not empirically validated production settings.
Step 4: Expose the NestJS endpoint
Create jev.controller.ts:
import {
Body,
Controller,
Post,
UseGuards,
} from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
import { JevService } from './jev.service';
import { TriageTicketDto } from './dto/triage-ticket.dto';
@Controller('ai')
@UseGuards(AuthGuard('jwt'))
export class JevController {
constructor(
private readonly jevService: JevService,
) {}
@Post('triage')
async triage(
@Body() dto: TriageTicketDto,
) {
return this.jevService.triageTicket(dto.message);
}
}
Register the controller and service in a NestJS module.
This endpoint assumes the application already has a configured Passport JWT strategy. Production deployments must also apply tenant-scoped authorization, rate limits, and the existing ticket ownership policies.
6. Connecting the Flutter Application
Now let’s integrate the backend with Flutter.
The mobile application will submit customer requests to NestJS without exposing the Jev API key.
Step 1: Install the HTTP package
flutter pub add http
Step 2: Create the service
Create ai_triage_service.dart:
import 'dart:convert';
import 'package:http/http.dart' as http;
class AiTriageService {
final String baseUrl;
AiTriageService(this.baseUrl);
Future<Map<String, dynamic>> classifyTicket({
required String message,
required String accessToken,
}) async {
final response = await http.post(
Uri.parse('$baseUrl/ai/triage'),
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer $accessToken',
},
body: jsonEncode({
'message': message,
}),
);
if (response.statusCode < 200 ||
response.statusCode >= 300) {
throw Exception('Ticket classification failed');
}
return jsonDecode(response.body)
as Map<String, dynamic>;
}
}
Step 3: Use the service in your Flutter screen
final aiService = AiTriageService(
'https://api.yourdomain.com',
);
Future<void> analyzeTicket() async {
final result = await aiService.classifyTicket(
message: ticketController.text,
accessToken: userAccessToken,
);
final department = result['department'];
final priority = result['priority'];
final requiresReview =
result['requiresHumanReview'] == true;
debugPrint('Department: $department');
debugPrint('Priority: $priority');
debugPrint('Human review: $requiresReview');
}
In a production application, display the result in a ticket status component, handle loading and error states, and keep access tokens in the application’s established authentication flow.
7. Testing the Complete Workflow
We can test the backend directly before connecting the Flutter interface.
Example API request
curl -X POST \
https://api.yourdomain.com/ai/triage \
-H "Authorization: Bearer $YOUR_APP_JWT" \
-H "Content-Type: application/json" \
-d '{
"message": "Our invoice was charged twice yesterday. Please reverse the extra payment. This is blocking our month-end closing."
}'
Illustrative application response
{
"department": "billing",
"priority": "high",
"requiresHumanReview": true,
"source": "jev"
}
This output demonstrates the expected API response format and a plausible routing decision. It is not a recorded live inference result.
In a deployed CRM, the result could create or update a ticket assigned to the Billing queue, set its suggested priority, and mark it as requiring approval.
The refund itself remains subject to authenticated user permissions and a separate approval workflow.
8. Best Use Cases for Jev in SaaS Applications
Jev becomes especially valuable when an application must evaluate large numbers of small, repetitive decisions.
ApplicationRecommended Jev use caseCRMLead classification, ticket routing, escalation detectionERPDocument categorization and approval recommendationsFinanceExpense categorization and suspicious-description reviewHRCandidate-to-role relevance and request classificationProject ManagementTask categorization and escalation signalsFlutter AppsIntent routing, content classification, feedback evaluation
For example, in a finance application, Jev might classify an uploaded expense description as travel, equipment, payroll-related, or another category.
But accounting calculations, payroll totals, tax rules, and treasury movements must remain deterministic and controlled by application code.
Where Jev Is Not the Right Tool
Jev should not replace a generative language model for conversational replies, article writing, complex explanations, or free-form text generation.
It should not replace a database query, arithmetic function, permissions engine, or deterministic validation rule.
A strong AI architecture uses each component for what it does best:
- Jev: Understanding, scoring, classification, and routing.
- LLM: Natural-language generation and complex conversational interactions.
- NestJS services: Validation, permissions, calculations, and business operations.
- Human reviewers: Ambiguous, sensitive, or high-impact decisions.
9. Building a Hybrid AI Architecture
One particularly useful pattern is to combine Jev with a general-purpose LLM.
Imagine a user typing this into a mobile CRM assistant:
“I want to know why my invoice hasn’t been approved.”
Instead of immediately passing the message to a potentially expensive general-purpose model, the backend can classify the user’s intent with Jev.
If the request is a simple status lookup, the backend retrieves the relevant invoice directly from PostgreSQL after enforcing authorization.
If the request requires a detailed explanation, the backend can send authorized, relevant information to a language model.
If the request asks to approve or modify a financial document, the backend follows the normal approval workflow and requests explicit confirmation.
This creates a hybrid architecture:
User Request → Jev Intent Classification → Authorized Workflow Selection → Database / Specialist LLM / Human Review
The benefits are architectural as much as financial: fewer unnecessary generative model calls, clearer responsibilities, and better control over which actions an AI-assisted system can perform.
10. Pricing and Performance
According to TypeSafe’s published model pricing on October 16, 2026, Jev is listed at:
$0.042 per million input tokens, with no charge for output tokens.
The published price applies to Jev 1.13 and Jev 1.14. Actual spending depends on request size, question structure, traffic, and account terms.
A particularly interesting production case study was published on October 7, 2026.
AI recruiting platform Jack & Jill reported an 88% reduction in model costs for one of its candidate-screening workflows after adopting Jev, with comparable measured accuracy and approximately twice the processing speed.
Those are results from a specific deployment, not performance guarantees for other applications.
Developers should benchmark Jev on their own datasets before replacing an existing model.
11. Production Best Practices
A successful proof of concept is only the beginning. A reliable production integration needs several additional protections.
1. Keep credentials server-side. Mobile clients communicate with your authenticated backend, not with Jev directly.
2. Use confidence-based routing. Send uncertain classifications to human review rather than automatically acting on every result.
3. Keep financial and security decisions deterministic. Jev can recommend a route or flag an issue, but authorization and approval rules must remain in code.
4. Protect customer data. Minimize the state you send to an external model. Avoid unnecessary personal details, tokens, sensitive financial records, and cross-tenant information.
5. Implement a safe fallback. When the model is unavailable, retain the request for manual review instead of silently dropping it.
6. Measure real accuracy. Build a labeled dataset of tickets, test multiple categories, evaluate false positives and false negatives, and tune thresholds accordingly.
7. Evaluate non-English inputs carefully. TypeSafe states that English remains Jev’s strongest language. Arabic-language workloads, including Egyptian Arabic, should be tested separately before production automation.
8. Monitor models and costs. Log the evaluated model version, question identifiers, decision metrics, token usage, and final action without exposing sensitive customer content.
For multi-tenant SaaS applications, it is especially important to enforce the same tenant isolation and role-based permissions that govern every ordinary API request.
12. Final Thoughts
Adding AI to software should not mean sending every request to a chatbot.
Many business applications need something much more specific: small, reliable, structured decisions that fit inside existing workflows.
Jev provides a useful foundation for that type of intelligence.
By combining Jev with NestJS and Flutter, developers can build applications that automatically classify information, identify priorities, recommend workflows, and escalate uncertain situations.
The strongest implementation does not give the AI unlimited control.
Instead, it uses AI for interpretation, conventional software for rules and execution, and human judgment where the consequences demand it.
The goal isn’t to make AI run your entire system. It’s to make your system smarter while keeping it under control.
Official Resources
- TypeSafe AI
- Official Jev Documentation
- Developer Console
- JavaScript SDK
- API Reference
- Model Versions and Pricing
- Confidence-Based Routing
This tutorial demonstrates the documented API and a proposed application architecture. The integration code has not been executed against a live Jev account; generated decisions must be tested and validated before production use.

Top comments (0)