JevCode / Getting started

Quick start

Get an API key, make your first Jev call with cURL or an SDK, and understand the response shape.

Source: docs.typesafe.ai/introduction/quickstartquickstartapisdk
Quick start: your first call in the terminal

Step 1: Try the Playground

Open the Playground and log in. Paste any text as the state:

Hi, I've been trying to connect my Stripe account for 3 days and it keeps failing.
I'm losing sales. Please help ASAP.

Then add a Noul question:

{
  "urgency": {
    "type": "noul",
    "instructions": "Does this message express urgency?"
  }
}

You get back a number between 0 and 1. Near 1 means the model thinks the answer is yes.

The Playground’s value is fast iteration: mix Noul, Choice, and Score questions, see every result from one call, and confirm your wording does what you expect.

Step 2: Get an API key

Create one in the dashboard, then set the environment variable:

export TYPESAFE_API_KEY="sk-..."

Step 3: Call the API

Every model is served by the same endpoint:

POST https://api.typesafe.ai/v1/systemone
Authorization: Bearer <API_KEY>
Content-Type: application/json

Minimal runnable cURL example:

curl -X POST https://api.typesafe.ai/v1/systemone \
  -H "Authorization: Bearer $TYPESAFE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "jev-latest",
    "state": "Hi, I have been trying to connect my Stripe account for 3 days and it keeps failing. I am losing sales. Please help ASAP.",
    "questions": {
      "department": {
        "type": "choice",
        "instructions": "Which team should handle this",
        "criteria": {
          "billing": "Payment or subscription issues",
          "technical": "Bugs or integration problems",
          "sales": "Pricing or account questions"
        }
      },
      "frustration": {
        "type": "score",
        "instructions": "How frustrated the customer appears",
        "criteria": [
          "Calm, just stating facts",
          "Frustrated but civil",
          "Very angry, strong language"
        ]
      },
      "is_urgent": {
        "type": "noul",
        "instructions": "The message conveys urgency"
      }
    }
  }'

The SDKs read TYPESAFE_API_KEY from the environment and call jev-latest by default.

Python

pip install typesafe-sdk     # or: uv add typesafe-sdk
from typesafe_sdk import AsyncTypeSafeClient, Choice, Noul, Score

async def main() -> None:
    async with AsyncTypeSafeClient() as client:
        response = await client.system_one(
            state={"document": "I was charged twice. Please fix this ASAP."},
            questions={
                "billing": Noul(instructions="Is this ticket about billing?"),
                "tone": Choice(
                    instructions="What is the customer's tone?",
                    criteria={"calm": None, "frustrated": None, "angry": None},
                ),
                "urgency": Score(
                    instructions="How urgent is this ticket?",
                    criteria=["can wait", "this week", "today"],
                ),
            },
        )

    print(response.nouls["billing"].noul)
    print(response.choices["tone"].choice)
    print(response.scores["urgency"].score)

TypeScript / JavaScript

npm install @typesafe-ai/sdk    # requires Node.js 20+
import { choice, TypeSafeClient } from "@typesafe-ai/sdk";

const client = new TypeSafeClient();
const response = await client.systemOne({
  state: { document: "I was charged twice. Please fix this ASAP." },
  questions: {
    category: choice("What is this ticket about?", {
      billing: null,
      technical: null,
      other: null,
    }),
  },
});

console.log(response.answers.category.choice);

The TS SDK’s main advantage is that answer types are inferred from your questions: the questions you pass determine the return type, so a misspelled field name is a compile error.

What the response looks like

Each answer’s type follows the question’s type:

Type Fields Meaning
choice choice / probabilities / confidence Selected option, distribution over options, confidence
score score / legend / probabilities / confidence Position along your levels (can fall between two), legend, distribution, confidence
noul noul Probability the answer is yes. No separate confidence.

The key constraint: answers are always confined to the options you supplied. The model returns a probability distribution over your options, never a value outside them — so no parser is needed to recover meaning.

Common pitfalls

  • The state is read once. The model reads it once, then evaluates all questions in parallel. Pack multiple questions into one request early; it costs almost nothing.
  • Pre-process non-text input. Images, audio, and video must be converted to text or structured fields before being sent as state.
  • Over-limit returns 429. The official SDKs retry with backoff and honour the retry-after header by default; calling the HTTP API directly means implementing that yourself.

Next steps

  • Choice — the basis of classification and routing
  • Score — rating and ranking
  • Noul — verification and guardrails
  • Confidence — use it to control system behaviour