Skip to content

Noemad Docs

SDK & CLI

Client configuration, payment-aware transports, tools, and recovery.

Integration guide · planned capabilities. Model-specific capabilities, usage rates, and x402 upto settlement require backend implementation and validation. The preview runs local samples; documented contracts do not imply live availability.

Implementation target. This guide specifies the intended product surface. The current frontend uses local samples; it does not call an inference service or collect funds. An endpoint is enabled only after its adapter, ownership, usage, and payment behavior are qualified.

Planned API origin. Examples use https://noemad.dev/v1, the intended product API path. The API is not connected in this frontend preview. MODEL_ID_FROM_DISCOVERY and NOEMAD_API_KEY are placeholders, not published credentials or model IDs. A product API key identifies an account; a separate payment-aware transport must handle spending authorization.

Compatible inference needs a payment-aware transport

The standard SDK body and stream formats remain useful, but a plain bearer-key client cannot authorize a wallet debit. A costed request can return HTTP 402 with a quote. A user-owned transport or local proxy must review requirements, obtain the permitted signature, preserve X-Quote-ID, and retry the same operation.

No maintained Noemad SDK, CLI installer, or bridge package has been published in this preview. The following examples define the integration surface; they are not claims that any generic client is already fully compatible.

Python SDK shape

Python · configuration example
import os
from openai import OpenAI

client = OpenAI(
    base_url="https://noemad.dev/v1",
    api_key=os.environ["NOEMAD_API_KEY"],
)

# A bare SDK call needs a payment-aware transport before live use.
response = client.chat.completions.create(
    model="MODEL_ID_FROM_DISCOVERY",
    messages=[{"role": "user", "content": "Summarize the brief."}],
    max_tokens=1024,
)
print(response.choices[0].message.content)
Python · streaming shape
stream = client.chat.completions.create(
    model="MODEL_ID_FROM_DISCOVERY",
    messages=[{"role": "user", "content": "Explain the next step."}],
    max_tokens=1024,
    stream=True,
)
for chunk in stream:
    if chunk.choices and chunk.choices[0].delta.content:
        print(chunk.choices[0].delta.content, end="")
# Handle terminal errors and retrieve the separate payment receipt.

Use SDK hooks or an explicit transport wrapper to handle the payment handshake; do not keep resubmitting the request on 402. The service still validates the complete response and final usage. The consumer must treat an interrupted stream as incomplete.

Inspect a request with curl

Shell · placeholder endpoint
curl https://noemad.dev/v1/chat/completions \
  -H "Authorization: Bearer $NOEMAD_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"MODEL_ID_FROM_DISCOVERY","messages":[{"role":"user","content":"Hello."}],"max_tokens":100}'

# This does not sign or pay. A costed endpoint can return HTTP 402.
# Inspect the requirements in a payment-aware client.

Messages-compatible CLI configuration

json
{
  "env": {
    "ANTHROPIC_BASE_URL": "https://noemad.dev",
    "ANTHROPIC_AUTH_TOKEN": "NOEMAD_PRODUCT_KEY_PLACEHOLDER",
    "ANTHROPIC_DEFAULT_OPUS_MODEL": "MODEL_ID_FROM_DISCOVERY",
    "ANTHROPIC_DEFAULT_SONNET_MODEL": "MODEL_ID_FROM_DISCOVERY",
    "ANTHROPIC_DEFAULT_HAIKU_MODEL": "MODEL_ID_FROM_DISCOVERY"
  },
  "model": "opus"
}

This is the archived configuration pattern for a Messages-compatible CLI. Map each slot to an actually qualified model. Keep the key in protected local configuration or the client’s supported secret mechanism. Restart existing sessions or warm workers after changing configuration.

A desktop bridge is a separate integration requiring a maintained, signed implementation and a local permission model. No desktop installer is linked from this preview.

Responses-compatible CLI configuration

TOML · integration template
model = "MODEL_ID_FROM_DISCOVERY"
model_provider = "noemad"
model_reasoning_effort = "medium"

[model_providers.noemad]
name = "Noemad"
base_url = "https://noemad.dev/v1"
wire_api = "responses"

# Authentication and payment transport must be configured using the
# installed CLI version's supported mechanism. No signer is uploaded.

The archived client integration used command-backed authentication and a discovered model catalog. A maintained Noemad integration must pin the client version, test the response lifecycle, protect local key files, and provide a payment-aware transport without embedding private keys in configuration.

Reasoning choices must come from the selected model. Do not expose a fixed universal list or assume a command-line flag is accepted by every client version.

OpenAI-compatible provider configuration

json
{
  "provider": {
    "noemad": {
      "npm": "@ai-sdk/openai-compatible",
      "name": "Noemad",
      "options": {
        "baseURL": "https://noemad.dev/v1",
        "apiKey": "NOEMAD_PRODUCT_KEY_PLACEHOLDER"
      },
      "models": {
        "MODEL_ID_FROM_DISCOVERY": {
          "name": "Qualified model"
        }
      }
    }
  },
  "model": "noemad/MODEL_ID_FROM_DISCOVERY"
}

This illustrates the OpenCode-style provider/model mapping preserved by the source frontend. The provider key is a client configuration name; the model ID must come from product discovery. A payment-aware local transport can be the configured base URL once implemented.

Tool integration directory

Client / toolPreserved configuration surfaceNoemad integration requirement
Claude CodeMessages base URL, auth token, model slotsPayment-aware transport and compatible content/tool blocks
Claude Desktop bridgeLocal bridge setup and model selectionMaintained signed bridge; explicit local permissions
Codex CLIResponses provider, model catalog, reasoningPinned client schema, streaming, bounded local signing
OpenCodeCustom compatible provider and modelsPreserve unrelated config and provider/model mapping
Grok BuildCustom endpoint, key, default modelQualify the installed client’s transport and tool lifecycle
OpenClawCompatible provider and selected modelDiscover capabilities and verify a safe sample request
PiLocal model registry, API adapter, thinking levelsPreserve model capabilities and local agent policy
HermesConfig and environment provider settingsUse supported config commands and secret storage
AiderOpenAI-compatible API base and model selectorPayment transport, safe retries, and tool verification
ContinueEditor model provider, API base, model IDKeep credentials outside source control
CursorCustom model base URL and API key settingsConfirm client support for payment extension
curl / custom HTTPBearer auth, content type, JSON / multipartExplicit quote handling; no automatic signing

Future setup tools must create timestamped backups and preserve unrelated settings. Never advertise a one-command installer until the script is maintained, reviewable, and tested. Do not pipe a placeholder URL into a shell.

Additional manual configuration patterns

Shell · compatible environment
# A compatible CLI may read these variables.
export OPENAI_API_BASE="https://noemad.dev/v1"
export OPENAI_API_KEY="$NOEMAD_API_KEY"
# Select MODEL_ID_FROM_DISCOVERY in the installed client's model setting.
json
{
  "models": [
    {
      "title": "Noemad",
      "provider": "openai",
      "model": "MODEL_ID_FROM_DISCOVERY",
      "apiBase": "https://noemad.dev/v1",
      "apiKey": "NOEMAD_PRODUCT_KEY_PLACEHOLDER"
    }
  ]
}

The JSON illustrates the archived editor configuration shape. Current client versions can use different schemas. Verify against the chosen version before writing a user’s configuration. Secrets are placeholders and must not be committed to a repository.

Planned Go invocation flow

Go-style pseudocode
policy := LoadUserSpendingPolicy()
request := BuildCompatibleRequest()
challenge := RequestOrReadQuote(request)
policy.Check(challenge) // origin, model, limits, chain, asset, recipient, max

authorization := LoadOrSignSameBoundedAuthorization(challenge)
PersistQuoteAndAuthorizationJournal(challenge, authorization)
output := InvokeSameOperation(request, challenge.ID, authorization)
receipt := PollOwnerPaymentStatus(challenge.ID)
return output, receipt

The signer stays local or in the user’s chosen wallet. Pin cumulative budget, maximum per request, deadline, concurrency, allowed model scopes, facilitator, and proxy. A language model may propose a request but cannot raise its own spending cap or change the recipient.

Crash recovery and receipts

Persist quote ID, request binding, authorization identity, and operation state before submission. Resume the same state after a crash. A lost response does not justify a new nonce, a new paid operation, or duplicate tool execution.

Keep inference state separate from collection state. After a stream ends, poll GET /api/v1/payments/{quote_id} for actual cost and the verified receipt. Pending and unknown operations still count toward the local outstanding-spend policy until reconciled.