Developer API
Available now: text chat, streaming and per-key usage. Open Usage → Developer access after connecting and verifying your wallet.
Connect your applications to Noema’s cloud models using the credits already available in your wallet account. Give each application its own key, allowed models, expiry and lifetime spending limit.
Create a key
- Connect and verify your wallet, then open Usage → Developer access.
- Choose Create key, name the application and set a dollar-denominated lifetime budget.
- Select allowed models and an expiry. Zero-retention only is the default. Allowing labelled provider retention is optional.
- Save the key when it appears. It cannot be shown again.
Keep keys in server environment variables. Never put them in frontend code, URLs or a public repository. Revoke a lost key and create a replacement. Revocation blocks new requests; requests already accepted can finish.
A key’s budget does not add credits. The key and the wallet both need enough available credit for a request. Active reservations count toward the limit; successful requests settle at the measured charge. Failed or cancelled requests release their reservation. Changing a key’s permissions or budget requires revoking and replacing it.
First request
Base URL: https://app.noemanetwork.xyz/api/v1
The following example runs on a server with the openai JavaScript package. Set NOEMA_API_KEY privately. A caller-generated UUID identifies one logical request.
import OpenAI from 'openai';
import { randomUUID } from 'node:crypto';
const noema = new OpenAI({
apiKey: process.env.NOEMA_API_KEY,
baseURL: 'https://app.noemanetwork.xyz/api/v1',
maxRetries: 0,
});
const requestId = randomUUID();
const reply = await noema.chat.completions.create({
model: 'noema-auto',
messages: [{ role: 'user', content: 'Write a short project checklist.' }],
max_tokens: 512,
}, { headers: { 'Idempotency-Key': requestId } });
console.log(reply.choices[0].message.content);noema-auto lets Noema Router choose a cloud model. The selected underlying route is kept private. This hosted API does not run inference on your device or connected hardware.
Streaming
const stream = await noema.chat.completions.create({
model: 'noema-auto',
messages: [{ role: 'user', content: 'Outline a simple landing page.' }],
max_completion_tokens: 512,
stream: true,
stream_options: { include_usage: true },
}, { headers: { 'Idempotency-Key': randomUUID() } });
for await (const chunk of stream) {
process.stdout.write(chunk.choices[0]?.delta.content ?? '');
if (chunk.usage) console.log(chunk.usage);
}Chunks use chat.completion.chunk, followed by [DONE]. Reported token usage arrives at the end when requested. It may be absent if the provider did not report it or the stream was interrupted. An error after streaming begins is an error event, not a successful completion. Treat partial output as incomplete.
Choose a model
GET /models lists models permitted by your key and its retention policy. Each entry includes a public ID, display name and a noema object with retention and current prices. Prices are in micro-USD per million tokens and include Noema’s service costs. One dollar equals 1,000,000 micro-USD.
For a named model, use its returned ID and acknowledge the returned price version:
const catalogue = await noema.models.list();
const model = catalogue.data.find(item => item.id !== 'noema-auto');
if (!model) throw new Error('This key has no available named models.');
const response = await fetch('https://app.noemanetwork.xyz/api/v1/chat/completions', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.NOEMA_API_KEY}`,
'Content-Type': 'application/json',
'Idempotency-Key': randomUUID(),
},
body: JSON.stringify({
model: model.id,
messages: [{ role: 'user', content: 'Explain this task in three steps.' }],
max_tokens: 512,
noema: {
price_version: model.noema.price.version,
...(model.noema.retention_version
? { retention_version: model.noema.retention_version }
: {}),
},
}),
});
if (!response.ok) throw new Error(`Noema request failed: ${response.status}`);
console.log((await response.json()).choices[0].message.content);The additional noema fields are extensions to the common API format. TypeScript clients should use a typed extension or a plain HTTP request to access them. Refresh the model list if the price or retention version changes; Noema rejects stale selections instead of silently accepting different terms. Requests fail if no permitted route is available.
Privacy and data
The key’s policy is enforced for every accepted request. A zero-retention key cannot be weakened by a caller. A request can require zero retention using X-Noema-Privacy-Policy: zero-retention. Local-only policies reject hosted requests; the API cannot redirect work to your hardware.
Protect sensitive text before sending it. An external application does not automatically run Noema’s browser ZKR. The API receives the text you submit, and permitted cloud providers process it. Zero retention is a provider-routing policy, not a hardware attestation or a claim that content never leaves your machine.
Keys cannot read your browser’s conversations, files, project context or memories. Noema stores key permissions and billing metadata, including request IDs, timing, token counts and charges. The API does not store prompts or answers for later retrieval. Usage stays associated with the funding wallet.
Usage and retries
Use GET /usage?page=0 with the same Bearer key to view that key’s budget, spend, reservations and requests. Pages contain up to 50 requests and hasMore indicates whether another page is available. Wallet owners can see all their keys in Usage.
Successful responses include compact noema billing metadata: request ID, charge state, reported cost, retention and zkr: caller-managed. These are application records, not cryptographic execution proofs.
Reuse the same UUIDv4 Idempotency-Key when checking an uncertain attempt. A repeated accepted ID returns 409; it never dispatches again. A changed payload with the same ID also returns 409. Check /usage for the original state. Responses cannot be replayed because their content is not stored.
Omitting the header generates a new request ID for each call. Automatic SDK retries without a stable ID can therefore create separate billable attempts. Disable automatic retries, or always supply and reuse your own ID. A new ID deliberately starts a new attempt.
| Status | Meaning | Action |
|---|---|---|
| 400 | Invalid or unsupported request | Correct the parameters or shorten the input |
| 401 | Key invalid, expired or revoked | Create or use a valid key |
| 402 | Wallet credit or key budget insufficient | Fund the wallet or replace the capped key |
| 403 | Model outside key permissions, or browser caller | Use a permitted model from server code |
| 409 | Duplicate ID, changed terms or privacy conflict | Check usage, refresh terms or choose an allowed route |
| 422 | Model could not complete the task | Review the task before a new attempt |
| 429 | Request or provider capacity limit | Wait before a new attempt |
| 503 | Service or provider unavailable | Check usage before retrying an uncertain attempt |
Supported surface
GET /models,POST /chat/completions,GET /usage.- One text completion;
system,developer,userandassistantmessages. End with a user message. - Up to 80 messages and 24,000 combined input characters.
- Either
max_tokensormax_completion_tokens, from 1 to 4,096. Default 4,096. - Optional
streamandstream_options.include_usage. - Up to three simultaneous reservations and 30 accepted requests per minute per key, subject to shared capacity.
- Up to ten active keys per wallet; expiry from one to 365 days.
Tool calling, the Responses API, multimodal input, image/video/audio generation, sampling controls and structured-output parameters are not part of this first API version. Unsupported fields are rejected rather than ignored. These API limits do not remove the media tools available inside the Noema app.
