loginsignup

Docs

Sublet connects GPUs at home to people who need LLM inference. Hosts earn credits; buyers get an OpenAI-compatible API.

Host quick start

  1. Sign up.
  2. On the machine with the GPU (Node 20+), run login. It prints a code and a link: open it and approve the code on this site. You do this once per computer.
  3. Run start once. The agent finds your GPU and the GGUF files on your disk, benchmarks, and goes online in the live rack.
  4. On the market, take a request that fits your GPU, or one that is ready now because the model is already on your disk. Then run the start command it shows. Nobody else can take it, and you have 15 minutes to start before it goes back to the board.
  5. The agent loads the model and passes a first model check, then the booking timer starts. Booked hours pay into your wallet when the timer ends.
host
once per computer: approve the code on the website
npx sublet-cli login --server https://sublet.duckdns.org
npx sublet-cli start
after you take a request on the market
npx sublet-cli start r_7Kq2…
npx sublet-cli jobs

No browser on the GPU machine? Create a host key in the host console and run npx sublet-cli login --key sh_… --server https://sublet.duckdns.org instead.

Test nodes (--simulation) cannot take paid work on the live server.

Reliability starts at 100%. Failed bookings, failed model checks, and lost connection lower it; see how Sublet checks hosts.

Buyer quick start

  1. Sign up: new accounts get free test credits.
  2. In the buyer console, create an API key (sk-…, shown once).
  3. Call an online host from the market per token, or post a booking: paste a HuggingFace .gguf link, pick hours and a price. A host takes it, loads the model, passes a model check, and the timer starts.
curl · pay per token
curl https://sublet.duckdns.org/h/<username>/v1/chat/completions \
  -H "Authorization: Bearer sk-your-api-key" \
  -H "Content-Type: application/json" \
  -d '{"messages":[{"role":"user","content":"Hello"}],"stream":true}'
python · openai sdk · booked
from openai import OpenAI

client = OpenAI(base_url="https://sublet.duckdns.org/r/<requestId>/v1", api_key="sk-your-api-key")
stream = client.chat.completions.create(
    model="sublet",
    messages=[{"role": "user", "content": "Hello"}],
    stream=True,
)
for chunk in stream:
    if chunk.choices:
        print(chunk.choices[0].delta.content or "", end="")

How Sublet checks hosts

Sublet does not take a host's word for which model it runs or how fast it is.

  • Hidden model checks. The server sends check prompts that look like normal jobs, during bookings and to hosts that sell calls. It compares the token probabilities in each answer with other hosts that run the same model file (same SHA-256), or with a trusted reference host.
  • Two failures end a booking. A failed check gets a second check right away. Two failures in a row end the booking: the buyer gets the money back for the time after the last good check, and the host gets a strike.
  • Holds. Two strikes in 7 days put a host on hold, and so does a reliability score below 90%. Held hosts cannot take requests or sell calls until Sublet reviews them.
  • Measured speed. The server measures each host's real tokens per second from the jobs it streams. The market shows that number and marks a host's own number as self-reported. A booking ends when the measured speed (the median of recent jobs) drops below the buyer's minimum, with a 20% margin for network jitter.
  • Reliability score. Completed bookings × passed checks × time connected while booked. Each part starts as if the host had nine good results, so one bad result does not hold a new host.

Limits

  • Hosts run the model on their own machine and can read prompts and answers. Do not send secrets.
  • A model with few hosts stays “unverified” until a second host or a reference host answers the same check.
  • Swapping in a different quantization of a big model is harder to detect than swapping in a different model.
  • The thresholds come from real llama.cpp measurements and will be tuned.

API reference

Send Authorization: Bearer sk-… with every call. The body is the OpenAI chat format: messages, max_tokens (default 256, at most 4096), temperature, stream.

methodpathwhat
POST/h/<username>/v1/chat/completionsPay per token. Billed from your credits at the host price per 1M input and output tokens.
POST/r/<requestId>/v1/chat/completionsYour active booking. Unlimited calls, $0 each: the escrow already paid for the hours.
GET/h/<username>/v1/modelsThe model the host is serving.
GET/api/liveServer-sent events: one `snapshot` of the public network every second.

Streaming

With "stream": true the response is OpenAI server-sent events. The final chunk has usage and sublet: { charged, costNanos }; booked calls report charged: false. Without streaming, the same two fields come in the JSON body.

final chunk
data: {"id":"chatcmpl-…","object":"chat.completion.chunk","choices":[{"index":0,"delta":{},"finish_reason":"stop"}],
       "usage":{"prompt_tokens":12,"completion_tokens":64,"total_tokens":76},
       "sublet":{"charged":true,"costNanos":19200,"host":"ava","requestId":null}}

data: [DONE]

Errors

Errors are JSON: { "error": "…" }.

401Missing or invalid API key.
402Not enough credits for the call or the booking.
404The booking does not exist or is not yours.
409The host is serving a booking, or your booking is not active.
503The host is offline, reconnecting, or held after failed checks.

Money

Amounts are integer nanos: 1 USD = 1,000,000,000 nanos. The server counts streamed chunks itself and never bills from the host's token count. Test credits only, no real money yet.

Models

Only HuggingFace .gguf file links are accepted, as a single file (not split):

model link
https://huggingface.co/<org>/<repo>/resolve/main/<file>.gguf

The server reads the size and SHA-256 from HuggingFace and estimates the VRAM the model needs. Hosts only load https://huggingface.co/ URLs.