Jev
Jev is TypeSafe's "System One" model. Instead of generating free-form text, you send it some state (a string, object or array) plus a set of typed questions, and it returns one structured answer per question - a probability, a chosen option, or a score. Answers come back in a few hundred milliseconds and cost a fraction of an LLM call, which makes Jev a good fit for classification, routing, moderation, ranking and other "narrow decision" tasks inside your code.
Endpoints
POST /proxy/v1/jev/systemone
GET /proxy/v1/jev/modelsThese proxy TypeSafe's API. Send the same JSON body you would send to TypeSafe, but authenticate with your Hack Club AI API key instead of a TypeSafe key.
Using the official SDKs
The proxy also serves /proxy/v1/jev/v1/systemone and /proxy/v1/jev/v1/models, which mirror TypeSafe's own paths. Point the TypeSafe JavaScript or Python SDK at https://ai.hackclub.com/proxy/v1/jev as the base URL and everything works unchanged. See the examples below.
Authentication
Authorization: Bearer YOUR_API_KEY
Content-Type: application/jsonRequest Body
| Parameter | Type | Required | Description |
|---|---|---|---|
state | string | object | array | Yes | The content to evaluate. A plain string for text, or structured data. |
questions | object | Yes | A map of question id to question. Each question is a noul, choice or score (see below). |
model | string | No | Model to use. Default: jev-latest. |
Question types
All three question types share type and instructions. Each adds its own criteria.
Noul - a yes/no question. Returns the probability the answer is yes (0 to 1).
{
"type": "noul",
"instructions": "Does this convey urgency?",
"criteria": {
"true": "Explicitly time-sensitive",
"false": "No urgency expressed"
}
}Choice - pick one option from a set you define. Returns the chosen option plus a probability for every option.
{
"type": "choice",
"instructions": "Which team should handle this?",
"criteria": {
"billing": "Payments, invoicing, refunds",
"technical": "Bugs, outages, integrations",
"sales": "Pricing, upgrades, new accounts"
}
}Score - rate the state along an ordered rubric. Returns a probability-weighted value that can land between levels. criteria must have at least two levels.
{
"type": "score",
"instructions": "How frustrated is the customer?",
"criteria": ["Calm", "Frustrated", "Very angry"]
}Example
curl https://ai.hackclub.com/proxy/v1/jev/systemone \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"state": "Help! My payouts have been failing for 3 days.",
"model": "jev-latest",
"questions": {
"is_urgent": {
"type": "noul",
"instructions": "Does this convey urgency?"
},
"department": {
"type": "choice",
"instructions": "Which team should handle this?",
"criteria": {
"billing": "Payments, invoicing, refunds",
"technical": "Bugs, outages, integrations",
"sales": "Pricing, upgrades, new accounts"
}
},
"frustration": {
"type": "score",
"instructions": "How frustrated is the customer?",
"criteria": ["Calm", "Frustrated", "Very angry"]
}
}
}'import { TypeSafeClient, noul, choice, score } from "@typesafe-ai/sdk";
const client = new TypeSafeClient({
apiKey: "YOUR_API_KEY",
baseURL: "https://ai.hackclub.com/proxy/v1/jev",
});
const result = await client.systemOne({
state: "Help! My payouts have been failing for 3 days.",
questions: {
is_urgent: noul("Does this convey urgency?"),
department: choice("Which team should handle this?", {
billing: "Payments, invoicing, refunds",
technical: "Bugs, outages, integrations",
sales: "Pricing, upgrades, new accounts",
}),
frustration: score("How frustrated is the customer?", [
"Calm",
"Frustrated",
"Very angry",
]),
},
});
console.log(result.answers.is_urgent.noul); // 0.92
console.log(result.answers.department.choice); // "technical"
console.log(result.answers.frustration.score); // 1.6from typesafe_sdk import TypeSafeClient, Noul, Choice, Score
client = TypeSafeClient(
api_key="YOUR_API_KEY",
base_url="https://ai.hackclub.com/proxy/v1/jev",
)
response = client.system_one(
state="Help! My payouts have been failing for 3 days.",
questions={
"is_urgent": Noul(instructions="Does this convey urgency?"),
"department": Choice(
instructions="Which team should handle this?",
criteria={
"billing": "Payments, invoicing, refunds",
"technical": "Bugs, outages, integrations",
"sales": "Pricing, upgrades, new accounts",
},
),
"frustration": Score(
instructions="How frustrated is the customer?",
criteria=["Calm", "Frustrated", "Very angry"],
),
},
)
print(response.nouls["is_urgent"].noul) # 0.92
print(response.choices["department"].choice) # "technical"
print(response.scores["frustration"].score) # 1.6Response
One answer per question, keyed by the same ids you sent. Every answer carries a type matching its question. choice and score answers also include a confidence between 0 and 1 derived from the probability distribution.
{
"model": "jev-1.13.0",
"answers": {
"is_urgent": {
"type": "noul",
"noul": 0.92
},
"department": {
"type": "choice",
"choice": "technical",
"probabilities": { "billing": 0.08, "technical": 0.85, "sales": 0.07 },
"confidence": 0.82
},
"frustration": {
"type": "score",
"score": 1.6,
"legend": { "0": "Calm", "1": "Frustrated", "2": "Very angry" },
"probabilities": { "0": 0.05, "1": 0.3, "2": 0.65 },
"confidence": 0.78
}
},
"usage": { "input_tokens": 312, "output_tokens": 48 }
}Models
GET /proxy/v1/jev/models lists the model names and aliases you can send in the model field.
| Alias | Description |
|---|---|
jev-latest | The most recent stable release. This is the default. |
jev-preview | The most recent release, including preview builds. |
The response's model field always reports the versioned id that answered (for example jev-1.13.0), so you can pin a specific version if you have tuned confidence thresholds against it.
Errors
| Status | Meaning |
|---|---|
400 Bad Request | The request body was not valid JSON. |
402 Payment Required | You've reached your daily spending limit. |
403 Forbidden | Your account is banned or needs identity verification. |
422 Unprocessable Entity | The body failed validation (missing field, malformed question). The response names the offending field. |
429 Too Many Requests | You hit the rate limit. Wait for the time in the Retry-After header. |
529 Overloaded | TypeSafe is temporarily overloaded. Retry after a short delay. |
Billing
Jev usage counts toward your normal Hack Club AI daily spending limit. Jev is charged per input token only (output tokens are free), and the proxy records the cost of every request based on the usage.input_tokens reported by TypeSafe.
Learn More
For all supported request and response fields, question types, and design patterns, see the TypeSafe documentation.