Solrouter
Build on Solrouter

Privacy SDK

Add encrypted AI calls to any app. Install @solrouter/sdk, pass your API key, and call client.chat(). The SDK encrypts the prompt on your machine.

Most AI APIs read your prompts in the clear. The Solrouter Privacy SDK encrypts your prompt before it leaves your machine, so the Solrouter backend cannot read it. The SDK handles the cryptography for you.

Here is what happens when you call client.chat(). The SDK fetches the enclave's X25519 public key from GET /tee/public-key. It does not fetch or verify the attestation quote. That check is a manual step. See the attestation guide. The SDK then encrypts your prompt on your machine with Arcium's RescueCipher. It sends the encrypted blob through the Solrouter backend, which forwards it without decrypting it. The TEE (Trusted Execution Environment, a CPU-isolated confidential VM) decrypts the prompt and calls the model on a Nosana GPU node. The node runs the model outside the enclave, so it sees the prompt and the reply in plaintext during inference. The reply comes back encrypted, and the SDK decrypts it with your session key.

Installation

Install the SDK from your package manager of choice.

npm install @solrouter/sdk
yarn add @solrouter/sdk
pnpm add @solrouter/sdk

Basic usage

This section walks through the calls you will make most often, starting with the default encrypted chat.

Encrypted chat (default)

Every call is encrypted unless you opt out. Create a SolRouter client with your API key and the production baseUrl, then start chatting.

import { SolRouter } from '@solrouter/sdk';

const client = new SolRouter({
  apiKey: 'sk_solrouter_...',
  baseUrl: 'https://api.solrouter.com',
});

// Encrypted on your machine. The Solrouter backend never sees plaintext.
const response = await client.chat('What are the risks of this DeFi protocol?');
console.log(response.message);

baseUrl is optional. Without it, SDK 1.1.0 calls the production backend host directly, which serves the same API as api.solrouter.com.

Choosing a model

Solrouter serves three open-weight models. The SDK type allows two strings, one of them retired. At runtime any other string passes through unchanged.

SDK stringBackend idStatusNote
gpt-oss-20bgpt-oss:20bLiveDefault. Use this with SDK 1.1.0.
none yetqwen3.8:27bLiveUncensored. Pass model: 'nosana:qwen3.8:27b' as any.
none yetqwen3-coder:30bLiveCoding. Pass model: 'nosana:qwen3-coder:30b' as any.
qwen3-8bnoneArchivedStill in the SDK type. The model is retired and not served.

A new SDK release with the current model map is Soon.

const response = await client.chat('Summarize the latest Solana validator outage', {
  model: 'gpt-oss-20b',  // the only typed live model string in SDK 1.1.0
});

After an idle period, a node can answer with a retryable "warming up" error. Wait a moment and send the request again.

Opt out of encryption (plaintext)

You can turn off client-side encryption for one call. The prompt then goes to the Solrouter backend in plaintext. The backend reads it and routes it to the same self-hosted Nosana models. No proprietary model is reachable this way.

const response = await client.chat('Hello', { encrypted: false });

In words, with encrypted: true (the default):

  • Your device encrypts the prompt with RescueCipher and an X25519 shared secret.
  • The Solrouter backend forwards the ciphertext. It cannot read it.
  • The TEE decrypts the prompt and calls the model at the configured Nosana endpoint URL. The node sees the prompt in plaintext.
  • The reply comes back encrypted to your session key.

In words, with encrypted: false:

  • Your device sends the prompt as plaintext.
  • The Solrouter backend reads the prompt and routes it to the same Nosana model.
  • The TEE is not used. No on-chain receipt is created.
  • The reply comes back in plaintext.

Guided reasoning (BRAID, agent path)

For questions that need structured analysis, route through the agent endpoint. Setting reasoning: 'braid' runs your request through BRAID guided reasoning. BRAID walks a fixed Guided Reasoning Diagram (GRD) of tool steps, then makes one synthesis call to the model. Older material calls this SERV.

This path is plaintext. The SDK sends the prompt to POST /agent without encryption and the response reports encrypted: false.

const response = await client.chat('Compare Marginfi vs Kamino lending on Solana', {
  reasoning: 'braid',  // plaintext path through the agent endpoint
});

Check balance

Calls draw from your plan first, then from USDC credit at $0.02 a call. Read the credit balance here.

const { balance, balanceFormatted } = await client.getBalance();

SDK options reference

Each of these options goes in the object you pass as the second argument to client.chat().

On the encrypted path, this leaves your machine: the ciphertext bundle (ciphertext, nonce, publicKey, version), plus in plaintext your API key, the model id, chatId, and any systemPrompt, useRAG, ragCollection, or useLiveSearch you set. The backend forwards only the bundle and the model id to the CVM.

OptionTypeDefaultDescription
modelstringgpt-oss-20bModel string. Use gpt-oss-20b with SDK 1.1.0. qwen3-8b is retired. Other backend ids pass through with a type cast.
encryptedbooleantrueTurn client-side encryption on or off for this call
reasoningstringnoneSet to 'braid' for guided reasoning. This path is plaintext.
chatIdstringnoneSent in plaintext to the backend. Not forwarded to the CVM.
systemPromptstringnoneSent in plaintext to the backend. Dropped before the CVM, so it never reaches the model.
useRAGbooleannoneSent in plaintext to the backend and ignored on the encrypted path.
ragCollectionstringnoneSent in plaintext to the backend and ignored on the encrypted path.
useLiveSearchbooleannoneSent in plaintext to the backend and ignored on the encrypted path.

Sign-up and pricing

Sign in at solrouter.com/sdk with an email address or a Solana wallet, with no KYC, and generate an API key. A plan covers your calls: Pro $9 for 2,000, Builder $49 for 12,500, or Scale $99 for 30,000, each per 30 days in USDC. See Pricing.

Each encrypted client.chat() call is one call to POST /tee/process. With your API key it draws one call from your plan. When the plan is used up, or you have none, it costs $0.02 from your USDC balance. With neither, the request fails with insufficient_funds (HTTP 402). The free messages from a web sign-in do not apply to API key calls. A call that fails in the enclave is not charged.

Solrouter runs only self-hosted, open-weight models on GPUs it rents: Qwen3.5 122B (qwen3.5:122b) inside an H200 GPU enclave on Phala whose host cannot read the prompt, and gpt-oss:20b, qwen3.8:27b, and qwen3-coder:30b on the Nosana decentralized GPU network, where the node that runs the model does see the prompt in plaintext during inference and Solrouter does not control that hardware. There are no third-party model APIs: no OpenAI, Anthropic, or Google. Your prompts never go to an external model provider.

On this page