26 de set. de 2026
Como chamar a API do Jev a partir de curl, Python e JavaScript
Uma primeira requisição /v1/systemone do Jev AI que você pode colar no terminal e depois no seu app — com uma resposta real, latência medida e a tabela completa de erros.
Antes da primeira chamada
O Jev responde decisões tipadas: você envia um estado mais perguntas nomeadas, e ele retorna uma das respostas que você declarou, com uma probabilidade. A Optio é um gateway operado de forma independente que encaminha a requisição ao Jev — você cria uma conta, abre o dashboard e cria uma chave de API. A chave completa é exibida exatamente uma vez e começa com jev_live_; guarde-a em um gerenciador de segredos do lado do servidor ou em uma variável de ambiente, nunca em código de frontend e nunca em um repositório Git.
O endpoint é o mesmo para todos os clientes:
POST https://jevai.website/api/v1/systemone
Authorization: Bearer $JEV_API_KEY
Content-Type: application/jsonEndpoint e cabeçalho de autenticaçãoA menor requisição útil
Um corpo de requisição tem duas partes: state (o assunto da decisão) e questions (o que você quer saber). O state pode ser uma string simples, um array de strings ou um objeto JSON, até 100,000 caracteres. As questions são um mapa de 1 a 8 perguntas nomeadas; o nome deve ser um identificador válido (letras, dígitos e underscores — ele vira a chave na resposta).
curl https://jevai.website/api/v1/systemone \
-H "Authorization: Bearer $JEV_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"state": "The payments webhook failed twice overnight. Should I wake up the on-call engineer?",
"questions": {
"page": {
"type": "noul",
"instructions": "Should someone be paged right now?",
"criteria": {
"true": "Revenue-impacting or data loss",
"false": "Can wait until morning"
}
}
}
}'
curl — uma pergunta sim/nãoOs valores em criteria são palavras suas — escreva-os como linhas de política. São eles que o modelo julga, então uma pergunta como “Devo acionar alguém de plantão?” com definições explícitas de true/false é muito mais repetível do que a mesma pergunta sem definições.
Como é a resposta
Uma resposta 200 real deste endpoint fica assim (capturada contra o gateway em produção; as contagens de tokens vieram da requisição real):
{
"request_id": "req_fe17d05411092c4f7f97947a",
"model": "jev-1.14.0",
"answers": {
"page": { "type": "noul", "noul": 0.91 }
},
"usage": {
"input_tokens": 128,
"output_tokens": 21,
"credits": 1,
"credits_remaining": 4
},
"latency_ms": 432
}
Resposta 200, abreviadaAs respostas são indexadas pelos nomes das suas perguntas, então ramificar no código é trivial: if (answers.page.noul < 0.8) escalate(). Toda resposta também carrega um request_id — cite-o quando escrever para o suporte e registre-o do seu lado para conciliação.
Os três tipos de pergunta
- noul — sim/não. Retorna noul: a probabilidade (0–1) de a resposta ser sim. criteria com descrições true/false é opcional, mas recomendado.
- choice — escolha uma entre 2–20 opções rotuladas. Retorna choice (o rótulo selecionado), probabilities por opção e um valor de confidence.
- score — posiciona o estado em uma escala ordenada de 2–10 níveis, ex. [Calm, Frustrated, Very angry]. Retorna um score contínuo (0 = primeiro nível), probabilidades sobre os níveis, uma legend que mapeia as faixas de score de volta aos rótulos, e confidence.
Até oito perguntas cabem em uma requisição — isso importa para o custo, porque a cobrança é por token de entrada com mínimo de 1 crédito, não por pergunta. Três perguntas sobre o mesmo estado custam o mesmo que uma, sempre que o total ficar abaixo de 1,000 tokens.
Interpretando a resposta em Python e JavaScript
import os, requests
resp = requests.post(
"https://jevai.website/api/v1/systemone",
headers={"Authorization": f"Bearer {os.environ['JEV_API_KEY']}"},
json={
"state": {
"ticket": {"subject": "Refund duplicate charge", "order": "A-104"},
"refund_policy": "Duplicate charges are eligible for a full refund.",
},
"questions": {
"policy_supports": {"type": "noul", "instructions": "Does the policy support this refund?"},
"frustration": {"type": "score", "instructions": "How frustrated is the customer?",
"criteria": ["Calm", "Frustrated", "Very angry"]},
},
},
timeout=30,
)
resp.raise_for_status()
answers = resp.json()["answers"]
if answers["policy_supports"]["noul"] > 0.9:
print("auto-approve; frustration =", answers["frustration"]["legend"])Pythonconst resp = await fetch("https://jevai.website/api/v1/systemone", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.JEV_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
state: "Charged twice for order A-104, please refund the duplicate.",
questions: {
route: {
type: "choice",
instructions: "Which team handles this?",
criteria: {
billing: "Payments, payouts, invoicing, refunds",
technical: "Bugs, outages, integrations",
sales: "Pricing, upgrades, new accounts",
},
},
},
}),
});
const { answers, usage, latency_ms } = await resp.json();
console.log(answers.route.choice, answers.route.probabilities, latency_ms);JavaScript / TypeScriptCódigos de erro e retentativas
Os erros sempre usam um único formato: {error: {code, message, request_id}}. Ramifique pelo code, não pelo texto da mensagem. A tabela:
- 401 missing_api_key / invalid_api_key — sem cabeçalho Bearer, ou a chave foi revogada. Não tente novamente.
- 402 insufficient_credits — o saldo do workspace não cobriu a reserva. Não tente novamente; recarregue.
- 422 invalid_request — corpo malformado, nomes de pergunta inválidos, zero perguntas, state acima de 100,000 caracteres. Não tente novamente; corrija a requisição.
- 429 rate_limited — o teto de concorrência ou de requisições por minuto do plano foi atingido. Tente novamente com backoff exponencial; a resposta traz os cabeçalhos Retry-After e X-RateLimit-Remaining.
- 502 upstream_error (também upstream_timeout, upstream_unreachable) — o provedor do modelo falhou ou a janela upstream de 15 segundos expirou. Tente novamente com backoff; você não foi cobrado.
- 529 upstream_overloaded — capacidade do provedor. Mesmo tratamento do 502.
import time
def decide(body, max_retries=3):
for attempt in range(max_retries + 1):
resp = requests.post(URL, headers=HEADERS, json=body, timeout=30)
if resp.status_code in (429, 502, 529):
time.sleep(min(2 ** attempt, 8))
continue
resp.raise_for_status()
return resp.json()
raise RuntimeError("upstream kept failing; give up or degrade")Loop de retentativa em Python que vale copiarOs créditos são reservados antes de o modelo rodar e liquidados depois contra a contagem real de tokens; se o provedor falhar, a reserva é devolvida automaticamente. Uma requisição com falha nunca deixa uma cobrança no ledger.
Quanto custa e quão rápido responde
Um crédito equivale a 1,000 tokens de entrada; a cobrança é ceil(tokens de entrada / 1,000), mínimo 1, e os tokens de saída são gratuitos. No teste acima, uma requisição de 401 tokens com duas perguntas custou exatamente 1 crédito. No pacote Starter ($10 = 100,000 créditos), isso dá $0.0001 por decisão.
Latência: em 16 chamadas reais sucessivas em um único dia útil, a latency_ms reportada se concentrou entre 400–560 ms tanto para requisições de uma quanto de duas perguntas, com mediana perto de 445 ms. A primeira chamada depois de um período ocioso teve um cold start ocasional de ~3 s; caudas mais longas não foram observadas nesse tamanho de amostra. Defina seu timeout pelo p99 da sua própria região em vez de confiar nesta única medição.
Posso fazer mais de 8 perguntas em uma requisição?
Não — o limite é de 8 perguntas por requisição. Divida o restante em uma segunda requisição sobre o mesmo estado, ou mova as perguntas de menor valor para um caminho mais barato em lote.
Onde consigo meus primeiros créditos gratuitos?
Todo novo workspace começa com 5 créditos gratuitos, e o playground é gratuito no navegador (30 execuções por dia de forma anônima, 50 quando logado). Cinco créditos bastam para validar uma decisão com dados reais antes de pagar qualquer coisa.
Este é o endpoint oficial da TypeSafe?
Não. A Optio é um gateway independente para chamar o Jev e não tem vínculo com a TypeSafe. O formato da requisição segue o mesmo contrato /v1/systemone, então clientes existentes podem apontar para ele.
Teste o playground do Jev AI para enviar sua primeira decisão gratuita depois de terminar este guia.