How an agent works.
An agent is a pons coin plus a signed set of typed questions. Its budget is the coin's creator fees. Its endpoint runs the questions over whatever state you send.
Call an agent
POST JEVLABS_HOST/v1/agents/<id>
Authorization: Bearer jp_<id>_<wallet>_<mac>
Content-Type: application/json
{ "state": <string, object or array> }
The gateway adds the agent's published questions, forwards to Jev, and returns one answer per question under the question's id. Choice and Score also carry per-option probabilities and a confidence; Noul is the probability of yes.
{
"model": "jevlabs",
"door": 0,
"agent": { "id": 0, "name": "Transfer risk", "config": "0x…" },
"answers": {
"risk": { "type": "score", "score": 1.7, "probabilities": { "0": 0.06, "1": 0.18, "2": 0.76 }, "confidence": 0.81 },
"hold": { "type": "noul", "noul": 0.88 }
},
"usage": { "input_tokens": 96, "output_tokens": 16 }
}
The raw door is also open: POST /v1/systemone with your own questions in the body, same key, same budget.
Question types
| choice | criteria maps each option to what it means. Returns the choice, per-option probabilities and a confidence. |
| score | legend maps ordered integer levels to what they mean. Returns a score, probabilities per level and a confidence. |
| noul | criteria with true and false. Returns the probability the answer is yes. |
Jev does not write, chain reasoning, count, or look outside the state you send. Use it for the snap judgments inside software: classify, route, score, detect, rank, verify, guard. Keep an LLM for the prose.
Keys
A key is jp_<agent>_<wallet>_<mac>, issued when the wallet signs this message and the same every time for that agent and wallet:
Jevpad key coin: <agent id> address: <wallet, lower case> issued: <ISO time, within ten minutes>
POST /api/key
{ "id": 0, "address": "0x…", "issued": "2026-09-20T10:00:00.000Z", "signature": "0x…" }
→ { "key": "jp_0_0x…_…", "door": 0, "budget": "14692308600000000" }
If the agent has a minimum holding, the gateway reads the wallet's balance of the coin before issuing the key and again, cached for a minute, on every call. The launcher can change the minimum on chain at any time.
Configs
The launcher publishes the agent's questions by signing their canonical hash. The gateway stores the config with the signature and only accepts one signed by the coin's on-chain launcher.
POST /api/agent?hash=1 { "id": 0, "config": {…} } → { "hash", "message", "config" }
POST /api/agent { "id": 0, "address": "0x…", "config": {…}, "signature": "0x…" }
GET /api/agent?id=0 → { "id", "config", "hash", "launcher", "signature", "at" }
GET /api/agent?all=1 → every published config
JevLabs agent door: <agent id> config: <sha256 of the canonical config>
Canonical means JSON with object keys sorted, no whitespace. A config is a name, an optional description, and 1 to 16 questions with short identifiers.
Errors
| 401 | missing or invalid key, or a key for a different agent |
| 402 | the agent's budget is empty; push its fees or fund it |
| 403 | the agent asks for a minimum holding your wallet no longer has |
| 404 | the agent has no published config yet |
| 422 | bad body |
| 429 | over the per-key rate, 120 calls a minute |
| 503 | the gateway has no upstream key configured, or Jev is unavailable |
Metering and settlement
Each served call is one record in the gateway's usage log, batched into files whose names carry their record count. The operator settles on chain from that listing: settle(agent, calls, wei, ref), where wei ≤ calls × maxWeiPerCall, the batch is priced at TypeSafe's list rate at ETH spot, and ref is the hash of the file names billed. GET /api/usage?id=N&ref=<ref> returns the manifest and every file behind a settlement; each ref on an agent's ledger links there.
On chain
Contract … on Robinhood Chain.
| launch(params) | launches a pons v2 coin with a fresh sink as fee recipient, buybacks off, the launcher exempt from the snipe tax. |
| adopt(token, minHold) | makes a sink for a pons coin that already exists. The current fee recipient then hands the role to it on pons. |
| JevSink.collect() | sweeps the curve or pool, claims the escrow, deposits everything as the agent's budget. Anyone. |
| fund(id) | tops up a budget. Anyone. |
| setMinHold(id, n) | the launcher opens or gates the agent. |
| settle(id, calls, wei, ref) | operator only, capped per call, bounded by the budget, paid to the operator. |
| meter(id) | budget, funded, spent, calls, coverage, minHold in one read. |
There is no withdraw. address(this).balance == budgetTotal at all times. A pons community takeover can move a coin's fee role after its public timelock, which no recipient contract can prevent; routed(id) says whether the sink still holds it.
Jev