Skip to content
Reference

API reference

Two endpoints, Bearer keys, JSON in and out. VAKYN MAX and open-server serve the same API, and it is compatible with TypeSafe's Jev API, so code written for Jev works once it points at VAKYN and uses a key from it.

Basics

TopicDetails
Base URLVAKYN MAX: https://api.vakyn.com. Self-hosted: your open-server, e.g. http://localhost:8080 (no TLS built in; put a reverse proxy in front for HTTPS)
AuthenticationAuthorization: Bearer vk_… on every request. VAKYN MAX keys come from the console; open-server keys from vakyn keys create or its dashboard. A key works only where it was made
ContentJSON request and response bodies, UTF-8
EndpointsPOST /v1/systemone, GET /v1/models. No streaming and no batch endpoint.

POST /v1/systemone

Answer named questions about one state.

Request body

FieldTypeNotes
modelstring, requiredjev-latest or a name from GET /v1/models; anything else is a 400
statestring | object | array, requiredWhat the questions are about; not null
questionsobject, requiredAt least one entry: your name → a question (below). Answers come back in the same order
Question fieldnoulchoicescore
type"noul""choice""score"
instructionsoptional: string | object | array | nullsamesame
criteriaoptional: { true?, false? }, each string | object | array | nullrequired: object of 1–255 options, name → string | object | array | nullrequired: array of 1–10 levels, lowest first, each string | object | array

Fields the server does not know are ignored.

Response body

FieldTypeNotes
modelstringThe concrete model that answered (the alias is resolved)
answersobjectYour question names → answers, in request order
usage.input_tokensintegerTokens the model read for this request
usage.output_tokensintegerAlways 0: nothing is generated
assets_usednullKept for compatibility
AnswerFields
noultype, noul (probability of yes), stats
choicetype, choice (the most likely option), confidence, probabilities (option → probability, in criteria order), stats
scoretype, score (expected level), legend ("0"… → your level descriptions, unchanged), probabilities ("0"… → probability), confidence, stats

Probabilities, confidences and scores are rounded to two decimals. stats is always an empty object. Confidence formulas are on the Confidence page.

curl -s "https://api.vakyn.com/v1/systemone" \  -H "Authorization: Bearer $TYPESAFE_API_KEY" \  -H "Content-Type: application/json" \  -d '{    "model": "jev-latest",    "state": {      "channel": "email",      "customer": {        "plan": "team",        "seats": 12,        "months_active": 14      },      "message": "Since this morning nobody on our team can sign in. We have a client demo at 3pm."    },    "questions": {      "outage": {        "type": "noul",        "instructions": "Is the customer unable to use the product?"      },      "team": {        "type": "choice",        "instructions": "Which team should handle this?",        "criteria": {          "billing": "Invoices, charges and refunds",          "access": "Sign-in, passwords and permissions",          "product": "Bugs and how-to questions"        }      },      "urgency": {        "type": "score",        "instructions": "How soon does this need a reply?",        "criteria": [          "Can wait",          "Today",          "Within the hour"        ]      }    }  }'
Try it in the playground
{  "model": "vakyn-fake",  "answers": {    "outage": {      "type": "noul",      "noul": 0.91,      "stats": {}    },    "team": {      "type": "choice",      "choice": "access",      "confidence": 0.89,      "probabilities": {        "billing": 0.02,        "access": 0.93,        "product": 0.05      },      "stats": {}    },    "urgency": {      "type": "score",      "score": 1.86,      "legend": {        "0": "Can wait",        "1": "Today",        "2": "Within the hour"      },      "probabilities": {        "0": 0.01,        "1": 0.12,        "2": 0.87      },      "confidence": 0.79,      "stats": {}    }  },  "usage": {    "input_tokens": 112,    "output_tokens": 0  },  "assets_used": null}

GET /v1/models

Lists the model that answers and the jev-latest alias that points to it. Both names are accepted in model. On api.vakyn.com it lists the model behind VAKYN MAX.

curl -s "https://api.vakyn.com/v1/models" \  -H "Authorization: Bearer $TYPESAFE_API_KEY"
{  "models": [    {      "name": "vakyn-fake",      "description": "Deterministic fake engine for testing; answers are not meaningful.",      "release_date": "2026-10-02"    },    {      "name": "jev-latest",      "description": "Alias for vakyn-fake.",      "release_date": "2026-10-02"    }  ]}

Pricing

VAKYN MAXSelf-hosted
Input tokens$0.0294 per million, as counted in usage.input_tokensfree
Output tokensfree (always 0)free (always 0)
Errorsnot charged: only answered calls arefree
Payinga dollar balance per organization, topped up in the console; no subscriptionyour own hardware

Every question in a request is answered from one reading of the state, so a request with ten questions costs little more than one with a single question. When the balance reaches zero, VAKYN MAX refuses calls with a 402 instead of running into debt; the owners of the organization get an email when the balance runs low.

Limits

LimitValueOver the limit
State + the longest question32,768 tokens400 {"detail": {"error_type": "max_tokens_exceeded"}}
State + all questions65,536 tokenssame
Options in a choice1–255400 Too many choices. Must have at most 255 choices.
Levels in a score1–10400 Too many score levels. Must have at most 10 levels.
Requests admitted at onceopen-server: --max-queue, default 32429 with retry-after
Request body64 MiBThe token limits apply long before this

Requests over a limit are rejected, never truncated: an answer is always computed on everything you sent. Tokens are counted by the model's own tokenizer; as a rough guide, English text runs at about four characters per token. Input is text only.

Errors

Errors have a JSON body with a detail field. Both SDKs raise a typed error per status and expose the body, the status and the request id.

StatusWhendetail
400A limit is exceeded or the model is unknown; on VAKYN MAX also a body that is not JSONA message string, or { error_type } for token limits
401The key is missing, malformed, wrong or revokedA message
402VAKYN MAX only: the organization has no balance left{ error_type: "insufficient_balance", message }
404Any other path under /v1Not Found
422The body does not match the schema (open-server: or is not JSON)A list of { type, loc, msg, … } entries
429Every queue slot is takenA message; wait for retry-after
500The model failed on this requestA message
502VAKYN MAX only: the model service sent an answer that could not be read{ error_type: "bad_gateway", message }
503open-server: the model is still loading. VAKYN MAX: the model service is not availableA message; on VAKYN MAX { error_type: "service_unavailable", message }

401 Unauthorized

open-server answers Missing or invalid API key and also sends WWW-Authenticate: Bearer. VAKYN MAX answers Invalid API key. Create one at https://vakyn.com/console/keys.

curl -s "https://api.vakyn.com/v1/systemone" \  -H "Content-Type: application/json" \  -d '{    "model": "jev-latest",    "state": "Hello",    "questions": {      "greeting": {        "type": "noul",        "instructions": "Is this a greeting?"      }    }  }'
{  "detail": "Missing or invalid API key"}

402 Payment Required

VAKYN MAX only. The organization that owns the key has no balance left, so the call is refused before it reaches the model and costs nothing. Top up or redeem a code in the console; the next call goes through. In the SDKs it arrives as an API error with status 402.

{  "detail": {    "error_type": "insufficient_balance",    "message": "This organization has no balance left. Top up at https://vakyn.com/console/billing."  }}

422 Unprocessable Entity

loc points at the offending field: ["body", "questions", "q", "score", "criteria"] means the criteria of the score question named q.

curl -s "https://api.vakyn.com/v1/systemone" \  -H "Authorization: Bearer $TYPESAFE_API_KEY" \  -H "Content-Type: application/json" \  -d '{    "model": "jev-latest",    "questions": {      "greeting": {        "type": "noul"      }    }  }'
{  "detail": [    {      "type": "missing",      "loc": [        "body",        "state"      ],      "msg": "Field required"    }  ]}

400 Bad Request

curl -s "https://api.vakyn.com/v1/systemone" \  -H "Authorization: Bearer $TYPESAFE_API_KEY" \  -H "Content-Type: application/json" \  -d '{    "model": "jev-latest",    "state": "Rate this.",    "questions": {      "rating": {        "type": "score",        "criteria": [          "0",          "1",          "2",          "3",          "4",          "5",          "6",          "7",          "8",          "9",          "10"        ]      }    }  }'
{  "detail": "Too many score levels. Must have at most 10 levels."}
curl -s "https://api.vakyn.com/v1/systemone" \  -H "Authorization: Bearer $TYPESAFE_API_KEY" \  -H "Content-Type: application/json" \  -d '{    "model": "gpt-4o",    "state": "Hello",    "questions": {      "greeting": {        "type": "noul",        "instructions": "Is this a greeting?"      }    }  }'
{  "detail": "Unknown model 'gpt-4o'. Available models: vakyn-fake, jev-latest."}
{  "detail": {    "error_type": "max_tokens_exceeded"  }}

429 Too Many Requests

HTTP/1.1 429 Too Many Requestsretry-after: 1retry-after-ms: 1000x-typesafe-request-id: req_… {"detail": "Server is at capacity; retry after the delay in retry-after."}

Headers

HeaderDirectionMeaning
AuthorizationrequestBearer vk_…
Content-Typerequestapplication/json (the body is parsed as JSON either way)
x-typesafe-request-idresponseThe request id, on every response (open-server writes req_ plus 32 hex characters). Quote it when you report a problem; it is stored with each usage record
x-vakyn-request-idresponse (VAKYN MAX)The same id
retry-afterresponse (429)Seconds to wait before retrying
retry-after-msresponse (429)The same delay in milliseconds
WWW-Authenticateresponse (401, open-server)Bearer

Loading the docs…