NeuroForge API
30 September 2026 · Research preview. OpenAPI.
Make your first request
Find the available model and send it a message. You'll need curl and jq to run this example; your own app can use any HTTP client.
Base: https://neuroforge.io/v1. Keyless models, chat and search: omit Authorization. Valid private keys work; invalid keys are rejected. Anonymous CORS is credential-free.
set -e
model_id=$(curl --fail --max-time 15 -sS https://neuroforge.io/v1/models | jq -er '.data[0].id')
jq -n --arg model "$model_id" '{model:$model,messages:[{role:"user",content:"Hello"}],max_tokens:64,stream:false}' |
curl --fail --max-time 120 https://neuroforge.io/v1/chat/completions -H 'Content-Type: application/json' --data-binary @-
Models and availability
GET /models: check availability and choose the request profile by the returned ID: erais-fracture-gemma (hybrid), erais-dense-gemma4-e4b (dense) or erais-native-qwen3 (native). Use the erais metadata when present; it may be absent for the legacy hybrid profile. Dense and native discovery require it. Recorded native API/Discord selections share the World owner and completed a public response. Signed Discord delivery, assistant quality, sparse savings and paid readiness remain unqualified.
Chat
POST /chat/completions: text only. Resend alternating user/assistant history ending with the new user question. Token-context limits also apply. Limits depend on the model returned by discovery:
| Profile | Request and history | Output |
|---|---|---|
| Native ERAIS | Final question 2,048 UTF-8 bytes; at most three prior exchanges totalling 4,096 bytes; JSON 32,768 bytes | max_tokens 1–128, default 128; stream:false; n:1 |
| Hybrid or dense | Optional system message up to 8,192 UTF-8 bytes; at most 64 messages; other text 49,152 bytes total; JSON 98,304 bytes | max_tokens 32–2048, default 512; dense generation caps at 512; JSON or SSE |
Native instructions/sampling are deployment-owned: omit temperature and system messages. Hybrid and dense profiles allow only temperature:0, n:1. Unknown fields, tools, media, embeddings and Responses API are unsupported. Camera/microphone use the separate World visitor interface.
The composed native prompt must fit 512 tokenizer tokens; oldest complete exchanges may be retired. Byte limits do not guarantee token fit. Token-budget preflight is unavailable. Discovery exposes text only; World image perception does not enable API media. Its runtime_id identifies the owner; completions return model and usage without a runtime field. Rediscover after identity/unavailable errors. No silent fallback, token IDs or prompt echo.
JSON: choices[0].message.content and usage. Native output: ≤8,192 UTF-8 bytes. Hybrid/dense SSE: chat.completion.chunk deltas, finish_reason, then [DONE]. Interrupted output is incomplete; disconnect cancels cooperatively. Never auto-replay.
Search
POST /search: exactly {"query":"heat pumps"}; the raw query must be ≤500 UTF-16 code units. After NFKC normalization and cleanup, it must be 3–160 UTF-16 code units and ≤24 words; the UTF-8 JSON body must be ≤2,048 bytes. Queries containing URL-like or private-looking text may be rejected. The screening is a bounded heuristic, not a guarantee that private information will be detected. Up to three title/URL/content results; retrieved_at is lookup time. Untrusted search_snippets, not full pages or verified answers. source_status distinguishes results, partial results, no candidates and filtered candidates; a 502 may include an unavailable status and bounded diagnostic counts. An empty response does not establish that no sources exist.
Dense chat: start with Search the web for… or Look up…. Only the screened topic leaves. History/system text never triggers search. Retrieved sources are snippets; failed/empty lookups are labelled. Notices/links count towards bytes, not model tokens.
Capacity and deadlines
Hybrid: 16 jobs. Desktop dense: two slots, one API/Discord/World and one Minecraft; serialized generation. Native shares the World owner: eight visitor leases, two model jobs, one exclusive model turn and a non-model reserve. Leases do not mean simultaneous model execution. Unified learning and serving quality remain unqualified.
| Request | Origin | Edge | Client |
|---|---|---|---|
| SSE | hybrid 600s / dense 90s | 615s | 660s total, 30s idle |
| JSON | hybrid 105s / dense 90s | 115s | 120s |
| Native JSON | 45s including queueing | 50s including request body | 55s or longer |
| Search (8 concurrent) | 18s reader / 20s proxy | 22s | 30s |
Deadlines include queue/search/generation. SSE keep-alives every 10s add no tokens or time. Desktop Discord: 120s HTTP / 125s handler. Sinter's native path uses a 55s client deadline; its legacy path uses 660s Python / 700s browser.
Per minute: anonymous inference 24/network, 60 generations/edge; search 30/network, 120/edge; keys 60; shared guard 180/route namespace. Anonymous counters are separate. Edge-local rates are approximate, not global spending guarantees.
429/Retry-After: bounded backoff. 503: unavailable, not missing credentials. No transcript database or training added. Avoid sensitive inputs; verify answers.
Need help connecting?
Get help with the API. Tell us what you’re trying to connect, which endpoint you used and the public error code you saw. Leave out keys, prompts and private data.