Skip to content

Quickstart (5 min)

Your first five minutes: get a key → make one API call → (later) add the browser extension or other tools. Everything technical — receipts, checksums, the local proxy — is further down this page.

1. Get an API key

  1. Sign up free at app.cloakapi.io/signup.
  2. In the portal, open Integration → API keys (app.cloakapi.io/api-keys) and create a key. It starts with cloak_.
  3. Verify your email to unlock the $2 trial balance that model calls draw from.

No browser (CI, containers)? See Get a key without a browser below.

2. Make one API call

CloakAPI speaks the OpenAI API, but the gateway only relays requests that were tokenised on your own machine. A plain request sent straight to https://api.cloakapi.io/api/v1/chat/completions is refused: 403 engine_untrusted when it does not name an official CloakAPI tokeniser, 428 pretokenised_required when it is not signed as pre-tokenised. Nothing is relayed.

The shortest working path is the local proxy: it tokenises on your machine and adds the proof the gateway checks. Start it with your key (see Install & run), then point any OpenAI client at http://localhost:8799/v1.

curl:

Terminal window
curl http://localhost:8799/v1/chat/completions \
-H 'Content-Type: application/json' \
-d '{"model":"gpt-4o","messages":[{"role":"user","content":"Say hello"}]}'

Python (pip install openai):

from openai import OpenAI
client = OpenAI(base_url="http://localhost:8799/v1", api_key="unused") # the proxy holds your key
resp = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "Say hello"}],
)
print(resp.choices[0].message.content)

3. Optional tools, when you want them

  • Browser extension — cloaks what you type into ChatGPT, Claude, Gemini and Grok. Install steps · Downloads. Open it, choose Paste API key, and paste the key from step 1.
  • Desktop app (Windows, Linux) — Desktop.
  • SDKs — SDKs.
  • MiniShell — a tiny command-line tool, no account needed; see below.

Optional: MiniShell (command line, no account needed)

Run the one-liner installer. No account, no credit card, no dependencies. You get $2 of credit immediately — enough for hundreds of short calls to a small model (Claude Haiku). Completed replies carry a signed receipt (ECDSA-P256) when one is produced. Sign up later and we keep whatever balance is left for you.

Checksum files (sidecars): install.sh.sha256 · install.ps1.sha256 · install.exe.sha256

macOS / Linux:

Terminal window
curl -fsSL https://cloakapi.io/install.sh | sh

Windows (PowerShell 5.1+):

Terminal window
irm https://cloakapi.io/install.ps1 | iex

Verify the sha256 before running. Every sidecar is in sha256sum checkfile format, so on macOS / Linux run curl -fsSLO https://cloakapi.io/install.sh && curl -fsSLO https://cloakapi.io/install.sh.sha256 && sha256sum -c install.sh.sha256 and expect the line install.sh: OK. On Windows run Get-FileHash .\install.ps1 -Algorithm SHA256 and compare the printed hash with the one in the sidecar.

Once installed:

Terminal window
cloakapi chat "What is CloakAPI?"

Browser cloaking on chatgpt.com, claude.ai, gemini.google.com and grok.com uses the current Chrome extension (see Downloads for version and SHA-256) — install steps or Downloads. The extension is a separate install from the MiniShell command-line tool above. The Windows and Linux desktop builds are on the same Downloads page (Desktop); macOS is still coming.

The anonymous demo does not issue a receipt; MiniShell prints No receipt: the anonymous demo does not issue one. Receipts come with calls made with your own key, in the X-CloakAPI-Receipt-V2 response header. Keep that header value and verify it as shown in Verify the receipt. A bare JTI cannot be looked up with a cloak_ API key: POST /api/v1/receipts/verify with {"jti": …} answers 401 auth_required, with or without the key, and GET /api/v1/receipts/<jti> accepts only a signed-in portal session.


More on keys and the OpenAI SDK

Sign up at app.cloakapi.io and create a key under Integration → API keys. If you still had anonymous balance left when you signed up, it migrates to your account automatically.

No browser? (CI / headless / containers) Get a free-tier key with one curl — no GUI, no portal:

Terminal window
curl -sS -X POST https://api.cloakapi.io/api/v1/self-service/key \
-H 'Content-Type: application/json' -d '{}'
# → {"api_key":"cloak_…","tier":"free", …}
export CLOAKAPI_API_KEY=cloak_…

On-device tokenisation (SDK + MCP) works immediately with this key; LLM relay is balance-gated (verify email for a $2 trial). Full details, guard rails, and the email-attached variant: Authentication → Get an API key (headless / no browser).

Use any standard OpenAI or Anthropic client. Point it at the local proxy, which tokenises on your machine before anything is sent:

Terminal window
pip install openai
# or
npm install openai

Point your client at the local proxy

from openai import OpenAI
client = OpenAI(
base_url="http://localhost:8799/v1", # the local proxy, not api.cloakapi.io
api_key="unused", # the proxy holds your cloak_ key
)
resp = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "Summarise the attached email"}],
)
print(resp.choices[0].message.content)

Server-side only. SDK calls use bearer-token auth, which browsers won’t expose cross-origin from docs.cloakapi.io or arbitrary pages. If you need browser-side calls, run them from https://app.cloakapi.io (which is on the CORS credentialed allowlist) or proxy through your own backend. Direct fetches from the docs page itself are blocked by our CSP — paste the snippet into your own dev environment.

Verify the receipt

A completed non-streaming reply includes an X-CloakAPI-Receipt-V2 response header when a receipt is produced containing a base64-encoded (standard alphabet, padded) JSON OpenReceipt envelope. You get it on calls that reach the gateway with the pre-tokenised headers (SDKs, or the contract in Chat completions). The local proxy 0.3.0 does not pass this header through to your client. To verify it without an account, pass the header value verbatim:

Terminal window
# $RECEIPT = the entire X-CloakAPI-Receipt-V2 header value
curl -X POST https://api.cloakapi.io/api/v1/receipts/verify \
-H 'Content-Type: application/json' \
-d "{\"receipt\": \"$RECEIPT\"}"

The gateway accepts three payload shapes:

  1. Header value (base64 string) — {"receipt": "<header>"} (recommended; least typing)
  2. Decoded envelope object — {"receipt": {"v":2,"alg":"ES256",...}}
  3. JTI lookup — {"jti": "<jti>"} answers 401 auth_required, with or without a cloak_ key; GET /api/v1/receipts/<jti> accepts only a signed-in portal session

Or paste the envelope into the browser-based verifier at app.cloakapi.io/receipt-verifier.

A valid: true response means:

  • the schema is intact,
  • the signature was made by a key listed in the public JWKS (https://api.cloakapi.io/api/.well-known/cloakapi-receipt-pubkeys.jwks),
  • the chain prev_hash links into the previous receipt for the same tenant.

Offline verification (no gateway round-trip)

The envelope is independently verifiable. Decode the base64 header, canonicalise the JSON (sort keys, no whitespace), drop the sig and signature fields (both carry the same signature), SHA-256 it, then ECDSA-P256 verify with the public key whose kid matches envelope.kid in the JWKS. Read the envelope from the x-cloakapi-receipt-v2 response header of the call that produced it.

A reference Python verifier in 30 lines (uses cryptography):

import base64, json, hashlib, urllib.request
from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.hazmat.primitives.asymmetric.utils import encode_dss_signature
from cryptography.hazmat.primitives import hashes
def b64u(s): return base64.urlsafe_b64decode(s + "=" * (-len(s) % 4))
env = json.loads(b64u(receipt_header_value))
jwks = json.loads(urllib.request.urlopen(
"https://api.cloakapi.io/api/.well-known/cloakapi-receipt-pubkeys.jwks").read())
key = next(k for k in jwks["keys"] if k["kid"] == env["kid"])
env.pop("signature", None) # the envelope carries the signature twice
sig = b64u(env.pop("sig")) # drop both before canonicalising
canonical = json.dumps(env, sort_keys=True, separators=(",", ":")).encode()
pub = ec.EllipticCurvePublicNumbers(
int.from_bytes(b64u(key["x"]), "big"),
int.from_bytes(b64u(key["y"]), "big"),
ec.SECP256R1(),
).public_key()
pub.verify(
encode_dss_signature(int.from_bytes(sig[:32], "big"), int.from_bytes(sig[32:], "big")),
canonical,
ec.ECDSA(hashes.SHA256()),
)
print("PASS")

That’s it — completed replies now carry a signed receipt when one is produced. A receipt proves the record is intact and was signed by us; it does not by itself prove what was or was not detected in your text.

Where does tokenisation happen on this path? Nowhere — with a bare SDK pointed at api.cloakapi.io, the gateway is a blind relay: it does not inspect, detect or tokenise content on our servers, so a request your client has not tokenised is refused rather than forwarded. To have your PII tokenised, it must happen on your own machine — use the local proxy below (local proxy), or one of the other client-side ways (browser chat, desktop app, browser extension).


Option C — client-side drop-in (local proxy)

Run the CloakAPI local proxy on your own machine and point any OpenAI/Anthropic client at it. The proxy tokenises on your machine, then forwards only tokens through the CloakAPI gateway to your provider — detected identifiers are replaced before anything is sent (cloaked ≠ anonymous — bounded by published recall), and the gateway stays a blind relay (it sees only tokens) while it meters the call, signs the receipt, and bills the markup. Your provider, model and BYOK key choice are configured in your CloakAPI account — the proxy itself accepts no provider URL (it is gateway-locked by design, so every call can carry a receipt).

from openai import OpenAI
client = OpenAI(
base_url="http://localhost:8799/v1",
api_key="unused", # the proxy holds your CloakAPI key; provider keys live in your account
)
resp = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "Summarise the email from Alice."}],
)
print(resp.choices[0].message.content)

Configure the proxy with your CloakAPI keys by path (never on the command line):

Terminal window
CLOAK_API_KEY_FILE=/path/to/your/cloakapi-key # your CloakAPI tenant API key
CLOAK_TENANT_HMAC_KEY_FILE=/path/to/your/trust-key # per-tenant pre-tokenised trust key
# upstream is always the CloakAPI gateway (https://api.cloakapi.io/api/v1) —
# there is no provider-URL setting; BYOK provider keys live in your account.
# default listen address: 127.0.0.1:8799 (chosen to dodge RStudio/Jupyter/Dask)
# port taken? set CLOAK_PROXY_LISTEN=127.0.0.1:<free-port> and use the SAME
# port in your base_url above — the proxy never silently rebinds.

What’s covered. Structured PII — emails, phones, cards, national IDs, IBANs, IP addresses (~10 types) — is tokenised deterministically with no model, always on. Free-form personal names are protected by an optional on-device mini-AI (Ollama + Phi by default); with it running, names are tokenised on your machine, and by default, if it is unreachable the proxy fails closed rather than let a name leak.

Limits (honest).

  • Streaming is not yet supported — "stream": true returns HTTP 501 (planned for Phase 2).
  • The proxy is stateless per request — it only detokenises tokens whose originals were in that same request (fine for normal chat, which re-sends history). /v1/models and /healthz are available.

Round-trip a file

You’re not limited to text in, text out. Attach a document to any call (see File attachments) and the model’s response can be rebuilt into a real file — .docx, .xlsx, .html, and other formats — client-side, on the device that holds the alias map (reconstruction stays on that device). Format list, fidelity matrix, and the receipt claim: File rebuild (round-trip).