Getting started

Quickstart

Create a key, add credit, send your first request and verify the receipt it returns.

This guide takes you from a new account to a verified receipt. You need a terminal and, for the SDK examples, Node.js 20+ or Python 3.9+ with the official openai package installed.

1. Create an account

Sign up in the console at www.hushcompute.xyz/sign-up (opens in a new tab). Your account starts with a project. API keys, the balance, spending policy and receipts all belong to that project.

2. Create an API key

In the console, open API Keys and create a key. For this guide select the inference and receipts scopes. The full key is displayed exactly once; the platform keeps only its prefix and a keyed hash, so it cannot show the key again.

Shell
export HUSH_API_KEY="proj_live_..."

3. Add credit

Usage is prepaid. Open Billing in the console and choose one of:

  • USDG purchase. Approve USDG and call the credit router on Robinhood Chain. Credit is applied once the transaction has the required confirmations (3 by default). Purchased credit is non-withdrawable and can only be spent on platform usage.
  • Development credit. On local deployments with development credit enabled, grant up to $25.00 at a time. This option is never available in production.

Without credit, requests are rejected with HTTP 402 and error type insufficient_balance.

4. Send a request

Replace claude-haiku with any model returned by GET /v1/models on your deployment.

curl https://www.hushcompute.xyz/v1/chat/completions \
  -H "Authorization: Bearer $HUSH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-haiku",
    "max_completion_tokens": 256,
    "messages": [
      { "role": "system", "content": "You are a concise assistant." },
      { "role": "user", "content": "Explain what a signed receipt proves in two sentences." }
    ]
  }'

A successful response looks like this (hashes abbreviated):

200 OK
{
  "id": "req_01K58ZQ4W5V8E2R7PKD3N6A0TG",
  "object": "chat.completion",
  "created": 1789387200,
  "model": "claude-haiku",
  "choices": [
    {
      "index": 0,
      "message": { "role": "assistant", "content": "A signed receipt proves that ..." },
      "finish_reason": "stop"
    }
  ],
  "usage": { "prompt_tokens": 38, "completion_tokens": 52, "total_tokens": 90 },
  "receipt": {
    "id": "rcpt_01K58ZQ4W6N3T2B9XRC7D1M5HJ",
    "hash": "0x6f0d…a3c9",
    "signature": "0x9b1f…c07e1b",
    "signer": "0x3A4c…91De",
    "url": "https://www.hushcompute.xyz/proofs/rcpt_01K58ZQ4W6N3T2B9XRC7D1M5HJ"
  },
  "billing": {
    "request_id": "req_01K58ZQ4W5V8E2R7PKD3N6A0TG",
    "cost_micro_usd": "328",
    "cost_usd": "0.000328",
    "usage_estimated": false,
    "fingerprint_salt": "0x51c2…7f08"
  }
}

Before the model ran, the gateway reserved the maximum this request could cost. After it finished, it charged the exact cost shown in billing.cost_micro_usd and released the rest. See Usage for the calculation.

5. Inspect the receipt

The receipt object identifies the signed record of this request. The same ID is sent in the x-receipt-id header. Fetch the full receipt with a key that has the receipts scope:

Shell
curl https://www.hushcompute.xyz/v1/receipts/rcpt_01K58ZQ4W6N3T2B9XRC7D1M5HJ \
  -H "Authorization: Bearer $HUSH_API_KEY"

The response contains the canonical payload, its receipt_hash, the signature and the signer_address. The payload holds the model, token counts, cost, timing and salted fingerprints of the input and output, but no prompt or output text. Open receipt.url to see the public proof page.

6. Verify the receipt

Anyone can verify a receipt without an API key. Recompute the hash from the canonical payload and recover the address that signed it:

verify.ts
import { isAddressEqual, keccak256, recoverMessageAddress, stringToBytes, type Hex } from "viem";
import { canonicalize } from "./canonicalize"; // see Receipt Verification for the full function

const res = await fetch("https://www.hushcompute.xyz/api/proofs/rcpt_01K58ZQ4W6N3T2B9XRC7D1M5HJ");
const proof = (await res.json()) as {
  receipt_hash: Hex;
  signature: Hex;
  signer_address: Hex;
  payload: Record<string, unknown>;
};

const hash = keccak256(stringToBytes(canonicalize(proof.payload)));
const signer = await recoverMessageAddress({ message: { raw: hash }, signature: proof.signature });

console.log("hash matches:", hash === proof.receipt_hash.toLowerCase());
console.log("signed by stated signer:", isAddressEqual(signer, proof.signer_address));

Also compare the recovered address with the platform's published signer address. The complete procedure, including a Python version, Merkle inclusion proofs and fingerprint checks, is in Receipt Verification.

Where to go next

  1. Restrict the key to the models you use and give it a monthly limit: API Keys.
  2. Stream tokens and use tools: Chat Completions.
  3. Set a project budget: Budgets.