solidSF
Inference API by solidSF / Open beta 2026
Beta Operational Release 323adbd5855d · live since Sep 29 22:49 UTC
solidSF / Jesse / Open beta

Jesse.Weightless inference.

What it is

solidSF's deterministic Bayesian reasoning engine

One base URL. Your key.

Sign in on your account page for 60 free exchanges, create a key, and send a chat completion. Use the OpenAI-compatible endpoint below, or choose your app in the client setup section.

curl https://jesse.my/api/v1/chat/completions \
  -H "Authorization: Bearer $JESSE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "jesse-prod",
    "messages": [{"role": "user", "content": "What is 17 * 23?"}]
  }'

Try Jesse

Ask Jesse

Worked out, checked, or quoted.

Jesse is not a language model. Each request goes to the solver that can answer it: exact arithmetic, a unit table, a program Jesse runs against tests, a reference page. Every reply says which solver answered and whether the answer was checked. When no solver can answer, Jesse says so and explains why instead of guessing.

A / 01Math and units

Exact arithmetic at any size, fractions, percentages, equations, unit conversions, word problems. Work shown.

What is 2 to the power of 100?

A / 02Problems with proof

State the whole problem in one message. Add checks is … to name a second value from the same givens that lets you check the answer.

Compute 17 * 23 + 5. checks is the product before addition.

A / 03Code she ran

Ask with a command and something to check against, such as an example or an Input/Output sample. You only get code that passed its tests.

Write a Python function that reverses a string.

A / 04Facts, with the source

From Jesse's own references first, then a web search. The source is always cited. Start with Look up … to force a web search, or Fact-check: … to get a verdict weighed across sources.

A / 05Your memory and files

State a fact and Jesse keeps it for your key. Upload documents and Jesse answers from them, quoting the line.

A / 06Tables, puzzles, games

Convert tables between CSV, TSV, JSON, HTML and Markdown. Solve logic puzzles. Analyse a Go position or a Balatro hand.

A / 07QR codes

Make one for a link, text, an email address or a Wi-Fi network, as a PNG, an SVG and terminal text; Jesse decodes it back before you get it. Attach a photo or screenshot and she reads every code in it, without opening the links.

Make a QR code for https://jesse.my

Jesse can't yet write stories or essays, give opinions, work conditional probability, or act on your behalf. How to ask Jesse lists 100+ phrasings that are checked against the live service with every release.

Every answer comes with a receipt

The response is a standard chat completion plus a jesse object that says how the answer was produced. Check it in code: for example, trust verified: true answers and show the others with their source. A streamed reply (stream: true) carries the same jesse object on its last chunk, the one with finish_reason.

{
  "id": "chatcmpl-jesse-…",
  "object": "chat.completion",
  "model": "jesse-prod",
  "choices": [{ "index": 0, "finish_reason": "stop",
    "message": { "role": "assistant", "content": "17 * 23 = 391." } }],
  "usage": { "prompt_tokens": 12, "completion_tokens": 4, "total_tokens": 16 },
  "jesse": {
    "solver": "compute",
    "verified": true,
    "checked": "computed",
    "tried": ["compute:answered"]
  }
}
FieldMeaning
solverThe skill that answered: compute, reasoning, code_spec, lexicon, web_search, table_reformat, … help means nothing could answer, and the reply explains why.
verifiedtrue when Jesse computed the answer or ran and tested it. false when it is quoted from a source.
checkedHow it was checked: computed, spec_checks, lexicon_lead, web_search, or null.
phaseOn agent turns: where Jesse is in the task, as a checklist (stage, index/total, items with pending, in_progress or completed, done, and stopped with the reason when she stops). Claude Code shows it as its task list and Codex as its plan. On a pack or phase request it has an id: send "phase": {"id": …} back to resume the task.
call, callsA tool call Jesse proposes (solver: "tool"): {id, name, args, commit, pack, hook} for the first call, and calls for all of them. commit: true means running it changes something, so route it through your own approval. Present only when there is a call to run: no call means the answer is final. A call still out is listed in waiting, never proposed twice.
results, violationsOn the turn that reads tool results: each call with its own check (status established, sourced, unchecked, refuted or failed). verified is true only when every result passed a check (its outputSchema, or a commit's fields read back as asked); otherwise violations says why.
pack, schema, pristineThe pack the tools came from ({name, version, hash}), the schema a JSON reply was checked against ({id, ok, errors}), and on jesse-pristine the version of the baseline that answered.
triedThe solvers consulted, in order, and what each one did.
qrWhen the qr solver answered: for a code Jesse made, the code as png_base64 and svg with its check; for images you sent, the codes read from each one (the exact text, even where the reply leaves something out, such as a two-factor secret).
caveatAssumptions Jesse made while reading your request, when there were any.
noticeService status during the open beta, also sent as the X-Jesse-Notice header. shown: true means it was also put at the top of the reply, which happens on your first request of the day and after 30 minutes idle.

One engine, three behaviours.

Every model runs the same solvers. They differ in what they remember. GET /api/v1/models lists them.

M / 01 jesse-prod alias: jesse

The default. Remembers facts you state and prose corrections you send with your key, and they stay with that key. Code corrections are kept for review only: coding answers come only from Jesse's checked programs.

M / 02 jesse-pristine

The fixed baseline. Nothing you send changes it, so the same request returns the same answer. Use it for tests and comparisons.

D / 03 Memory and documents

GET /api/v1/memory shows what Jesse remembers for your key; DELETE erases it. Upload documents of up to 10,000,000 characters each (200 per key) and ask about them in later requests.

Open beta: be careful with confidential or export-controlled material. Your data is partitioned by API key and is never used for other customers' answers.

Use Jesse in your tools.

Start with your Jesse key. Choose your app, merge its settings, and select jesse as the model. The setup guide covers 33 clients, including Factory.ai and Oh My Pi.

01 / Coding agents Claude Code & Codex

Connect Jesse through Anthropic Messages or OpenAI Responses. Your agent runs tools and tests in your project.

Claude Code setup · Codex setup

02 / More coding agents Factory.ai & Oh My Pi

Use Factory's custom model in its CLI or desktop app, or add Jesse to OMP's model providers.

Factory.ai setup · OMP setup

03 / Editors & chat apps Choose your app

VS Code, Continue, Cline, OpenCode, Zed, JetBrains, Xcode, Open WebUI, LibreChat and more. Each guide identifies the connection your app supports.

Browse model connections

04 / Tools & custom apps MCP & chatbots

Expose Jesse as tools in an existing assistant, or use the SDK adapters for Slack, Discord, Telegram, Teams and your own app.

MCP connections · Chatbot adapters

Keep your key in your app's credential store or launch environment. Merge the setup into existing settings. MCP connects Jesse as a tool inside your assistant; it does not change that assistant's model. Factory's hosted web and mobile apps do not load local custom-model settings.

Build with the full API

Go beyond chat with streaming, answer receipts, per-key memory, documents, versioned tool packs, resumable agent phases and result checks. The SDK, MCP tool list and OpenAPI specification share one maintained contract.

Developer guidance · OpenAPI specification · API capabilities · Endpoint reference

Setup recipes are prepared; full sessions in every listed app have not been verified. Each guide shows its status. Jesse currently checks new functions and small programs; existing-code editing is not established.

Live on jesse.my, 27 Sep 2026: eight Jesse agents, four in Claude Code and four in Codex, no bridge. Each writes one module of a small package, runs its tests, checks the SHA-256 and runs them again. The harness's own pytest over all eight: 8 passed. 64 Jesse turns in 28 s, shown sped up.

How to ask

The tests in test_rev.py fail. Write a Python function reverse_string(s) that reverses a string, in rev.py. Then run `python3 -m pytest -q`.

Name the file, and end with the command that checks the work: pytest, python3 -m unittest, npm test, cargo test, go test or make test. Each turn of the agent is one request on your key, usually seven or eight for a task.

Today she writes new functions and small programs that her solvers can check, Python first. She does not edit existing code yet. When she cannot check a program she says so and changes nothing. With tools on the turn, the harness's system prompt is not used as task text.

The numbers.

Storage limited, for now
Pristine model 7,261,616 Priors

Version 323adbd5855d. Knowledge, grammar, research beliefs, web pages, Go and Wikipedia.

Largest customer model 7,261,666 Priors

The pristine model plus 50 priors one customer's agent has learned.

Request size, each 10M Characters

Characters per request and per document, about 2.5M tokens.

Average message latency 256 ms

Milliseconds, averaged over the last 1,000 chat messages, measured on the server.

  • MemoryIn progressGoal: 50 billion characters. Now: 500 MB of documents per account, searched on every request.
  • ContextIn progressGoal: no limit. Now: 10M characters per request; past that, your stored documents are searched.

Modalities

  • LanguageLiveChat and the API.
  • VisionIn progressNow: PDF pages and drawings in the vision lab. Coming soon: images in chat.
  • Audio (duplex)In progressNow: two-way room audio with speech recognition on our servers. Coming soon: Jesse's own voice, made on the server.
  • Voice (duplex)LiveTalk with Jesse, alone or with other people and up to four Jesses. Jesse's voice comes from your browser.
  • RoboticsLive, simulatedBodies, arms and drones that learn to move.
  • GamingLiveGo and other games.
  • FormalizationIn progressNow: research claims are checked in Lean 4 before they are published. Coming soon: formal proofs in chat.
  • Panel of ExpertsComing soonNot built yet.

One plan.

Developer / monthly
$20
Billed monthly by Stripe
Subscribe
  • TRYSign in with Google or GitHub for 60 free exchanges, shared by the chat and your API keys. No card needed.
  • KEYSTwo API keys per account. Need more? Each key pack adds 2 keys for $10 / month, as many packs as you like, from your account page. Every key gets the full rate limit below.
  • RATEPer key: 5 requests per second on average, in bursts of up to 4. No daily or monthly cap.
  • SIZE10,000,000 characters per request. Past 100,000 characters Jesse reads the beginning and end in full and searches the whole text for the sections relevant to the question; the reply says so.
  • MODELSjesse-prod (alias jesse) and jesse-pristine.
  • BILLINGChange your card, download invoices or cancel from the Stripe portal on your account page. Requests refused for their input are never billed.

Endpoints.

Base URL https://jesse.my/api/v1. Send your key as Authorization: Bearer jesse_live_… (or x-api-key). Never put it in a URL.

Chat

MethodPathPurpose
POST/chat/completionsOpenAI-compatible. Accepts model, messages (a system message sets the output format, for example "Reply as JSON with answer and confidence"), stream, tools, tool_choice, response_format (a json_schema reply is checked against its schema), and for agent graphs pack, phase and pipeline (below). Answers are deterministic, so temperature has no effect. Images in the last user message (image_url parts with a data: URI, PNG or JPEG) are read for QR codes; image links are not fetched.
GET/modelsThe models and their rate limits.
POST/messagesAnthropic Messages, for Claude Code and the Anthropic SDKs: model, system, messages (base64 image blocks are read for QR codes), tools, stream. Each call is one chat completion on your key; the answer carries the same jesse receipt. Client setup.
POST/responsesOpenAI Responses, for Codex: model, instructions, input (input_image data URIs are read for QR codes), tools, stream. Stateless: send the whole conversation (Codex does); previous_response_id is refused.
POST/messages/count_tokensAn estimate of the input tokens, for Anthropic clients.
GET/usageYour plan, key limit and packs, free exchanges left, and request counts: today, the last 7 and 30 days, per day, and per key.

Memory and feedback

MethodPathPurpose
POST/feedbackMark an answer right or wrong: {"completion_id", "rating": "positive" | "negative", "correction"}. The response says what happened to it (applied_to, effect). On jesse-prod, a prose correction is remembered for your key.
GET/memoryFacts Jesse remembers for your key ("my project uses Postgres", "remember that …"), plus your documents.
DELETE/memoryErase everything Jesse remembers for your key.
GET/agentWhat your key's agent has learned on top of the pristine priors.
POST/agent/resetBack to the latest pristine copy. Add {"documents": true} to remove your documents too.

Documents

MethodPathPurpose
POST/documentsStore {"name", "text"}. Completions on your key search it automatically.
POST/documents/upload?title=…Store a raw text body as a document.
PUT/documents/{name}Store or replace the document with this name: {"text"} or {"json"}, or the text itself. One name is one live document. Send If-Match: "<version>" to replace only the version you read; a stale version gets 409 version_conflict and nothing is written. If-None-Match: * means create only. Documents belong to your account (every key on it). query and upload are not document names.
GET/documents, /documents/{id}List your documents, or read one. A document stored by name has its version and text, and an ETag.
DELETE/documents/{id}Remove a document.
POST/documents/querySearch your documents directly: {"query", "k": 5}.

Agent graphs

Jesse can run as one node of an agent graph (LangGraph or similar). She proposes calls and checks results, and your graph runs them. She never calls a tool, a hook or a URL herself.

MethodPathPurpose
POST/packsStore a tool pack on your key: {"name", "tools", "pipelines", "schemas", "invariants"}. After that, a completion with "pack": "name" can call the pack's tools without resending their schemas. Every version has a hash; "pack": "name@sha256:…" pins that exact version. An unknown name or hash gets 404 pack_miss with jesse.pack_miss, and is not billed.
GET, PUT, DELETE/packs/{name}Read (?hash= for an older version), replace (If-Match for the version you read), or remove a pack. GET /packs lists them.
POST/checks{"state" | {"document": "name"}, "patch", "invariant" | "invariants"}: Jesse applies the patch (RFC 6902 or a merge patch) to a copy of the state and checks each invariant: no overlap, unique, required, range, sum_max, ref, schema, or "pack#id". Returns {ok, violations}. Nothing is stored.
POST, GET, DELETE/hooks, /hooks/{id}Register the URL of your hook runner for tools or a pack: {"url", "tools" | "pack"}. Jesse stores it and names it in call.hook, and never calls it.
POST/tools/resultsPost a call's result: {"call_id", "content" | "result"}. Jesse checks it at once ({verified, checked, violations}). The next turn that resumes the phase reads it, so you don't send the history again.
GET/tools/results/{call_id}A posted result and its check.

One graph step per turn: the first turn of a task (a pack request, or "phase": true) returns jesse.phase.id. Send {"phase": {"id": …}, "messages": [only the new ones]} to continue. Your node's system prompt is not read as the task, only what it allows or forbids. With "pipeline": "name", each turn proposes the next step of the pack's pipeline. A json_schema reply that does not fit its schema (inline, or "schema_id": "pack#id") is never sent as almost-JSON: content is null, refusal says why, and the receipt has solver: "help", checked: "schema".

# Store a pack once
curl https://jesse.my/api/v1/packs -H "Authorization: Bearer $JESSE_API_KEY" -H "Content-Type: application/json" -d '{
  "name": "calendar",
  "tools": [{"name": "calendar.free_slots", "commit": false,
             "description": "Find free slots between two times for a meeting of a given length.",
             "parameters": {"type": "object", "additionalProperties": false, "required": ["start", "end", "minutes"],
               "properties": {"start": {"type": "string", "format": "date-time"},
                              "end": {"type": "string", "format": "date-time"},
                              "minutes": {"type": "integer"}}}}]}'

# Then call it by name: no tools array
curl https://jesse.my/api/v1/chat/completions -H "Authorization: Bearer $JESSE_API_KEY" -H "Content-Type: application/json" -d '{
  "model": "jesse", "pack": "calendar",
  "messages": [{"role": "user", "content": "Find a free 30 minute slot from 2026-10-01T09:00:00Z to 2026-10-01T17:00:00Z."}]}'
# -> tool_calls, and jesse: {"solver": "tool", "verified": false, "call": {"name": "calendar.free_slots", "args": {…}, "commit": false, …}, "phase": {"id": "ph_…", …}}

Web

MethodPathPurpose
POST/web_search{"query", "max_results"}: the same search Jesse runs, returned as results with sources.
POST/research{"claim", "urls": [up to 4]}: Jesse gathers evidence for and against the claim and returns a research report with a verdict.
GET/beliefsJesse's belief ledger: claims and how evidence has moved them.

QR codes

MethodPathPurpose
POST/qr/encode{"text", "ecc": "L" | "M" | "Q" | "H", "border", "scale", "png", "svg", "text_art", "modules"}: the code as a PNG (png_base64), an SVG and terminal text, with its version and size. Jesse decodes the PNG back first: check.passed is true only when it reads exactly your text. Up to 2,953 bytes (level L; 2,331 at the default M). "modules": true adds the grid as rows of 0/1.
POST/qr/decode{"image": "<base64 PNG or JPEG, or a data: URI>"}, or the image itself as the body with Content-Type: image/png or image/jpeg (16 MB): every code found, with its text, version, ecc and corner bounds. Phone photos work: tilted, at an angle, or small in the frame.

In a chat, send the image as a message part, {"type": "image_url", "image_url": {"url": "data:image/png;base64,…"}} (Anthropic: an image block; Responses: input_image), and ask what it says, or ask for a code in words ("make a QR code for …", "a Wi-Fi QR code for network … password …"). The reply carries the result in jesse.qr.

# Make a code and save its PNG
curl https://jesse.my/api/v1/qr/encode \
  -H "Authorization: Bearer $JESSE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"text": "https://jesse.my", "ecc": "Q"}' | jq -r .png_base64 | base64 -d > qr.png

# Read every code in a photo or screenshot
curl https://jesse.my/api/v1/qr/decode \
  -H "Authorization: Bearer $JESSE_API_KEY" \
  -H "Content-Type: image/jpeg" \
  --data-binary @photo.jpg

Streaming

With "stream": true the reply arrives as OpenAI server-sent events: chat.completion.chunk objects, then data: [DONE]. The OpenAI SDKs handle this with stream=True.

Errors

Errors use the OpenAI shape: {"error": {"message", "type", "param", "code"}}. The message always says what to do next.

StatuscodeWhat to do
400invalid_json, invalid_requestFix the body. The message names the problem. Not billed.
400model_not_foundUse jesse, jesse-prod or jesse-pristine.
401missing_api_key, invalid_api_keySend Authorization: Bearer jesse_live_…. Keys are on your account page.
402free_prompts_usedYour 60 free exchanges are used. Subscribe to keep going.
403key_revoked, subscription_inactiveCreate a new key, or renew on your account page.
400invalid_pack, invalid_check, invalid_name, too_many_toolsThe message names each problem (for a pack, every tool Jesse cannot check and why). Nothing is stored.
404pack_miss, phase_miss, pipeline_miss, schema_miss, call_missThe pack, phase, pipeline, schema or call does not exist on this key (a phase expires 7 days after its last turn). pack_miss lists the packs the key has. Not billed.
405method_not_allowedCheck the method in the tables above.
409version_conflictSomeone wrote a newer version since you read it. Read it again (the error has current_version) and retry. Nothing was written.
429rate_limit_exceededWait for the time in Retry-After. Every response carries x-ratelimit-* headers.

If something fails inside Jesse, you still get a 200 with a reply that says so, never a bare 500. Check jesse.solver in code rather than relying on the status alone.