The protocolIntroducing $CREDIT, tokenized inferenceExplore ›
surplus
Account

Documentation

Surplus docs

One OpenAI-compatible API for every model, paid with CREDIT bought below face value on Robinhood Chain.

Get started

What Surplus is

Surplus is an LLM gateway billed in CREDIT. One CREDIT is $1 of inference. SURPLUS stakers earn CREDIT every hour and sell what they don't use on an order book, so buyers get the same models below list price.

Buyers

Buy CREDIT in USDG, activate it into an API balance, call any model with one key.

Stakers

Stake SURPLUS, earn CREDIT, use it yourself or list it for USDG.

Builders

Launch a token for your own Hugging Face model; if it graduates, Surplus serves it.

Get started

Quickstart

From wallet to first response in three steps.

  1. 01

    Buy CREDIT

    Pick an amount on the home page and pay in USDG. Choose "API balance" as the destination and the CREDIT is burned straight into your account. Already hold CREDIT in your wallet? Skip this: activate it from the account page.

    Buy credits →
  2. 02

    Create a key

    Sign in with your wallet on the account page and create a key. It starts with sk-surplus- and is shown once.

    Open account →
  3. 03

    Send a request

    Point any OpenAI-compatible client at the Surplus base URL. Model names, streaming and tool calls work as before.

    See endpoints →
curl
curl https://api.surplusllm.com/api/v1/chat/completions \
  -H "Authorization: Bearer $SURPLUS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "anthropic/claude-sonnet-5",
    "messages": [{ "role": "user", "content": "Hello" }],
    "max_tokens": 256
  }'
OpenAI SDK
import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://api.surplusllm.com/api/v1",
  apiKey: process.env.SURPLUS_API_KEY, // sk-surplus-…
});

const reply = await client.chat.completions.create({
  model: "anthropic/claude-sonnet-5",
  messages: [{ role: "user", content: "Hello" }],
  max_tokens: 256,
});
Env vars
# Any client that reads the OpenAI env vars
OPENAI_BASE_URL=https://api.surplusllm.com/api/v1
OPENAI_API_KEY=sk-surplus-…

API

Authentication

Base URL https://api.surplusllm.com/api/v1. Send your key as Authorization: Bearer sk-surplus-….

  • Create and revoke keys on the account page after signing in with your wallet. A key is shown once; only its hash is stored.
  • All keys on an account share one balance.
  • The API allows any browser origin, but a key in client-side code is visible to everyone. Call it from a server.

API

Endpoints

All paths are relative to the base URL.

GET/models

The model catalogue in OpenAI list shape, with per-token prompt and completion prices and context length. Cached for a few minutes.

Auth: None

POST/chat/completions

OpenAI Chat Completions, streaming or not. Responses carry x-surplus-request-id, and x-surplus-cost-usd when not streaming.

Auth: Key

GET/balance

Your account id and API balance in USD.

Auth: Key

GET/usage?limit=20

Your most recent requests: model, tokens, cost in USD, streaming or not.

Auth: Key

Only the OpenAI-compatible Chat Completions format is served today. An Anthropic-format /messages endpoint is planned, so the Anthropic SDK can't be pointed at Surplus yet.

API

How billing works

Requests are prepaid from your API balance. Parallel requests can never overdraw it.

  1. 01

    Fund

    Activating CREDIT burns it on Robinhood Chain and emits an Activated event. The gateway credits your balance from that event, once per transaction log, within about a minute (instantly when you buy on this site).

  2. 02

    Hold

    Before forwarding a request the gateway holds its worst-case cost: the prompt estimated from its length plus max_tokens at the completion price. Without max_tokens, output is capped to what your balance can pay for.

  3. 03

    Settle

    When the response finishes, the real cost is charged and the rest of the hold returns to your balance. If the provider errors, the whole hold is released.

Every request goes to zero-data-retention endpoints only. The gateway stores billing metadata (model, tokens, cost, timing), never prompts or responses.

API

Errors and limits

Errors use the OpenAI shape, so existing client error handling keeps working.

StatusCodeWhen
400invalid_request_errorThe body isn't valid JSON, or a field such as max_tokens is out of range.
401invalid_api_keyThe Authorization header is missing, malformed or the key was revoked.
402insufficient_balanceYour balance can't cover the request's hold. Top up and retry.
404model_not_foundThe model id isn't in GET /models.
413request_too_largeThe request body is larger than 4 MB.
429rate_limit_exceededMore than 120 requests a minute on one key.
502upstream_errorThe provider is unreachable. Other provider errors pass through with their own status. You are not charged.
Error body
{
  "error": {
    "message": "Rate limit exceeded: 120 requests per minute per key.",
    "type": "rate_limit_exceeded",
    "code": "rate_limit_exceeded"
  }
}

Protocol

CREDIT and the order book

Sellers list CREDIT at a discount off face value; buyers pay USDG and take the deepest discount first.

Face value
1 CREDIT = $1 of inference
Decimals
6, like USDG
Discount levels
Every 2.5%, deepest filled first
Platform fee
5% on top of the credit price
Referral
1.5% of the price, out of the fee
Gas
ETH on Robinhood Chain

Buying from a contract or an agent

  1. quote(credits) prices the purchase against the book.
  2. Approve USDG for the total plus a small slippage buffer.
  3. buy(credits, maxTotal, recipient, referrer) fills exactly that amount or reverts.
  4. buyAndActivate(…) does the same, then burns the CREDIT into an API account in one transaction.

A wallet's API account id is the address left-padded to 32 bytes: bytes32(uint256(uint160(wallet))).

Full walkthrough with Solidity on the $CREDIT page.

Protocol

Staking and selling

Emission is fixed per hour, so more stake means a smaller share each. Stakers' dollar return comes from buyers.

  1. 01

    Stake

    Stake SURPLUS in Staking. A fixed amount of CREDIT per hour is split across stakers by stake × time. Claim it any time.

  2. 02

    List

    sell(amount, discountBps) escrows your CREDIT at one discount level. Orders in a level fill first in, first out.

  3. 03

    Get paid

    Fills pay you in USDG. Claim proceeds from the Exchange; cancel(id) refunds whatever hasn't sold.

Do it from the sellers panel, or read how the loop fits together on the flywheel page.

Protocol

LLM launchpad

Launch a Pons token for your own Hugging Face model. If it graduates, Surplus deploys the pinned commit and serves it through the API.

  1. 01

    Bring your model

    Your own LLM on Hugging Face. Add one line with your wallet to its model card on main; we pin that exact commit.

  2. 02

    Launch on Pons

    You sign the launch from your own wallet, so Robinhood Chain records you as the deployer. The token trades on an ETH bonding curve.

  3. 03

    Graduate at 4.2 ETH

    When the curve fills, Pons moves the liquidity into a Uniswap v4 pool that is locked forever.

  4. 04

    Go live on Surplus

    We deploy the pinned commit and serve it through the Surplus API, paid in CREDIT like every other model.

Model requirements

  • Public repo, no access gate
  • Weights in safetensors, at most 9B parameters
  • A supported decoder architecture (Llama, Mistral, Qwen, Gemma, Phi, Granite, OLMo)
  • A chat template in tokenizer_config.json
  • A license that allows commercial serving (Apache-2.0, MIT, BSD-3, Llama 3.x, Gemma)
  • The line surplus-launcher: <your wallet> in README.md on main

Creator fee split

  • 60%Hosting vault. Keeps your model's GPU running. Every spend is on-chain with an invoice reference.
  • 30%You, the builder. Withdraw from your fee splitter any time, to any address you set. You also earn 30% of what your live model takes in on the Surplus API, as API balance.
  • 10%Burns $SURPLUS. Buys $SURPLUS on the market and sends it to the burn address.

Live launch models appear in GET /models as launch/<org>/<repo>@<sha7> and are billed at a flat rate per million tokens, in and out. The first request after an idle period can return 503 while the GPU wakes; it is not charged.

Start on the launchpad.

Protocol

Contracts

Robinhood Chain · chain 4663. Addresses read as zero until a contract is deployed.

CREDIT

The token. One CREDIT is one dollar of inference; `activate` burns it into API balance.

0x9975…16DA ↗

Staking

Stake SURPLUS here. Settles and mints each finalized hour's CREDIT.

0x33B1…99E0 ↗

Exchange

The order book: `sell`, `buy`, `buyAndActivate`, and seller claims.

0xeBf1…D25f ↗

SURPLUS

The token you stake for CREDIT, on Robinhood Chain mainnet.

0xE183…97EC ↗

USDG

Global Dollar: what buyers pay and sellers are paid in (ERC-20, 6 decimals). Gas is ETH.

0x5fc5…d168 ↗