Migrate from Jev
Sonoe implements the same HTTP API as TypeSafe's Jev: the same endpoint, the same questions and the same answers. Code written for Jev moves to Sonoe by changing two settings.
The short version
export TYPESAFE_BASE_URL="https://api.sonoeai.com"
export TYPESAFE_API_KEY="sk_sonoe_..." # a key from the Sonoe consoleThat's it. The official TypeSafe SDKs read both variables, so they send the same requests to Sonoe and get answers they understand. We test them against Sonoe as they are:
| SDK | Version tested | What we checked |
|---|---|---|
typesafe-sdk (Python) | 0.7.5 | system_one sync and async, nouls / choices / scores, request_id, models.list(), zstd-compressed bodies, 401 and 422 errors |
@typesafe-ai/sdk (JavaScript) | 0.7.0 | systemOne, withResponse(), models.list(), zstd-compressed bodies |
If you call the HTTP API directly, change the host from api.typesafe.ai to api.sonoeai.com and the key. The path (POST /v1/systemone), the body and the answers stay the same.
Model names
You don't need to change the model field. Sonoe accepts Jev's names as aliases of its own current model:
| You send | Sonoe uses |
|---|---|
jev-latest (the SDKs' default) | sonoe-latest |
jev-preview | sonoe-preview |
any jev-1.x.y, such as jev-1.13.0 | sonoe-latest |
sonoe-latest, sonoe-preview, sonoe-1.1.0 | Sonoe 1.1 |
The answer's model field tells you what actually answered: sonoe-1.1.0. Any other name returns 404. When you're ready, set TYPESAFE_DEFAULT_MODEL=sonoe-latest (or defaultModel in the JS client) so your logs say what they mean.
What stays the same
POST /v1/systemonewithstate,modelandquestions;GET /v1/modelsreturns{ "models": [...] }.Authorization: Bearer <key>.- Noul, Choice and Score questions, with
instructionsandcriteriaas strings, objects or arrays. - Answers:
noul;choice+probabilities+confidence;score+legend+probabilities+confidence. Answers come back under the question ids you chose. usage.input_tokensandusage.output_tokens.- Bodies compressed with
Content-Encoding: zstd(what the SDKs send from 1 KiB on) orgzip. - An
x-typesafe-request-idheader on every response. - Status codes:
401for a bad key,422for an invalid question (with the field's path),429when you're over a limit, withRetry-Afterso the SDKs wait the right time.
What's different
| Jev | Sonoe | |
|---|---|---|
| Images and Box questions | Supported (preview) | Not supported: 422. Sonoe reads text only. |
| Context | 64k tokens per request | Sonoe reads up to 256 tokens for each pair of (state + question, option). A longer state is cut at the end. |
| Request body | Up to 32 MiB | Up to 64 KiB (after decompression), or 413. |
| Questions per request | No fixed limit | Up to 64. |
| Choice options | Up to 255 | 2 to 255. |
| Score levels | Up to 10 | 2 to 10. |
usage.input_tokens | Tokens read | Tokens read: the state and question are read once per option, so many options or a long state cost more. |
usage.output_tokens | Small | Always 0. |
| Long context header | TypeSafe-Danger-Zone-Long-Context | Not available; the header is ignored. |
| Confidence | Derived from the probabilities | 1 − normalized entropy of the probabilities: 0 = no idea, 1 = certain. Comparable across 2 or 200 options. |
| Error messages | English | English by default; send Accept-Language: es, pt or fr to get them in that language. |
| Error body | JSON | error.type and error.message, plus detail (FastAPI style). Both SDKs read them. |
A few smaller details:
- Missing or
nullinstructionsare accepted: a Noul then uses itscriteria; a Choice or Score asks which option or level fits best. - A Noul's
criteria.trueandcriteria.falseare read as part of the question ("Yes means: …", "No means: …"). - Unknown top-level fields are ignored.
Check accuracy on your data
Sonoe 1.1 is a small multilingual model (a 118M-parameter cross-encoder based on multilingual-e5-small). It's fast and calibrated, but it's sensitive to wording in ways a larger model isn't. For example, on the state "I was charged twice. Please help ASAP.":
- "Is this about billing?" scored low, well under 0.5.
- "Is this about a payment or a charge?" scored about 0.97.
So, before you switch:
- Take a few hundred real requests you already know the right answer to.
- Send them to Sonoe (only the base URL changes) and compare with your labels and with Jev.
- Where Sonoe is wrong, try plainer words in
instructions, and give every Choice option a short description incriteriainstead ofnull. - Look at
confidenceon the misses: often you can route low-confidence answers to a person or a fallback instead of trusting them.
Checklist
- Create an account and a key at sonoeai.com.
- Set
TYPESAFE_BASE_URL=https://api.sonoeai.comandTYPESAFE_API_KEY=sk_sonoe_…(or change the host and key in your HTTP client). - Remove images and Box questions, or keep those requests on Jev.
- Keep each state short: Sonoe reads up to 256 tokens per option.
- Keep bodies under 64 KiB and requests under 64 questions.
- Compare accuracy on your own labeled data.
- Check your quota and per-minute limit in Errors and limits.
- Optionally set the default model to
sonoe-latest.