Overview#
EvaEsi is one model, EvaEsi 1.0. Every request goes to it. You choose how much work goes into an answer with a level: Look, Focus, Duet, High or Hyper. From Duet up, guests join the discussion before the answer is given. Usage is billed in rungs: a rung is one character of answer at Focus, and each level uses a set number of rungs per character of answer.
When you ask for live sources via web_search, retrieved sources come back on the response payload with an evidence_verdict. Code, structured edits and software-project work use the same model and the same contract.
Endpoint#
POST https://evaesi.dev/api/v1/responsesPass "level": "focus" in the JSON body, or omit level entirely. Focus is the default.
Levels#
| Level | What runs | Rungs per character of answer | Output per 1M rungs | Input per 1M rungs |
|---|---|---|---|---|
look | A short answer | 0.5 | £0.30 | £0.09 |
focus | A full answer | 1 | £1.20 | £0.36 |
duet | One guest joins, and they discuss before answering | 2.5 | £3.00 | £0.90 |
high | Two guests join the discussion | 3.5 | £4.20 | £1.26 |
hyper | Three guests join the discussion | 4.5 | £5.40 | £1.62 |
Guest discussion is hidden work, capped at a number of rounds per request. Output sizes rise with the level to make room for longer answers.
Limits#
| Field | Value |
|---|---|
| Max input rungs | 100,000 |
| Max output rungs | 32,000 at Look and Focus, 64,000 from Duet up |
| Requests at a time, per room | 1, queued |
Prompt validation enforces a 100,000-rung hard cap on the prompt field at the API edge. Empty prompts return 400 EMPTY_PROMPT.
Billing#
Input and output rungs are metered separately at the level's price and reported on both the response body (usage object) and headers. The level's rungs per character are already applied to the reported usage.
Headers on a successful non-stream response:
x-evaesi-input-rungs: 29
x-evaesi-output-rungs: 118
x-evaesi-total-rungs: 147
x-ratelimit-limit: 300
x-ratelimit-remaining: 287Request body#
| Field | Type | Required | Description |
|---|---|---|---|
prompt | string | Yes | The question or instruction, up to 100,000 rungs. |
level | string | No | look, focus, duet, high or hyper. Default focus. |
web_search | boolean | No | Retrieve live sources and return them with an evidence_verdict. |
stream | boolean | No | Server-sent event streaming. |
max_output_rungs | integer | No | A ceiling on the answer, within the level's maximum. |
Response#
{
"request_id": "req_8f3a...",
"content": "Generated answer...",
"sources": [],
"sources_url": "/api/v1/sources/req_8f3a...",
"evidence_verdict": null,
"usage": {
"input_rungs": 29,
"output_rungs": 118,
"total_rungs": 147
},
"model": "evaesi-1.0",
"level": "focus"
}sources_url returns the same-origin path /api/v1/sources/{request_id} while the gateway still holds the live source bundle.
Examples#
cURL
curl -X POST https://evaesi.dev/api/v1/responses \
-H "Authorization: Bearer esi_dev_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"prompt": "Compare the 2024 and 2026 UK energy policy reforms.",
"level": "duet",
"web_search": true,
"max_output_rungs": 2048
}'Python
import requests
response = requests.post(
"https://evaesi.dev/api/v1/responses",
headers={"Authorization": "Bearer esi_dev_YOUR_KEY"},
json={
"prompt": "Compare the 2024 and 2026 UK energy policy reforms.",
"level": "duet",
"web_search": True,
"max_output_rungs": 2048,
},
)
data = response.json()
print(data["content"])
print(f"sources cited: {len(data['sources'])}")
print(f"verdict: {data.get('evidence_verdict')}")JavaScript
const response = await fetch("https://evaesi.dev/api/v1/responses", {
method: "POST",
headers: {
"Authorization": "Bearer esi_dev_YOUR_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
prompt: "Compare the 2024 and 2026 UK energy policy reforms.",
level: "duet",
web_search: true,
}),
});
const data = await response.json();
console.log(data.content);
console.log(`sources: ${data.sources.length}, verdict: ${data.evidence_verdict}`);