For information only. Not advice, and not to be relied on. What that means, in full
Integration guide

Connect your systems to the policy router

Your application sends its AI requests to https://governai.space/api/v1/route instead of calling a model provider directly. Nothing is installed on your side: you need an account, a key, a policy, and one HTTPS call from your server. Every decision comes back with a reference to a tamper-evident audit record you can export later.

1. Getting set up

Three people are involved, and most of it is done in the console.

We create your organisation

There is no self-serve sign-up. We create your organisation, set its regulator and monthly budget, and send your first administrator a sign-in.

Your administrator

Signs in and turns on two-factor at Security. Writes the policy at Policies, issues a key at Keys, and invites reviewers at Team.

Your engineer

Puts the key in your server’s secret store, replaces the provider call with the request below, and handles the five decisions and the failure codes.

A key is shown once, when it is issued. It belongs to one organisation, carries its own per-minute rate limit, and holds one or more scopes: route — call the policy router; read — see recent decisions for your own organisation; evidence — export the complete audit record for a period, with hashes. Give each system its own key with only the scopes it needs.

2. The first call

Send the name of your policy, the model you want, what the request is for, and the prompt. The examples read the key from an environment variable, which is where it belongs.
curl
curl -s https://governai.space/api/v1/route \
  -H "authorization: Bearer $GH_KEY" \
  -H 'content-type: application/json' \
  -d '{
    "policy": "your-policy-slug",
    "model":  "hf-eleutherai-pythia-160m",
    "use":    "summarisation",
    "prompt": "Summarise this complaint for the case file: ..."
  }'
Node.js (18 or later)
const res = await fetch('https://governai.space/api/v1/route', {
  method: 'POST',
  headers: {
    authorization: `Bearer ${process.env.GH_KEY}`,
    'content-type': 'application/json',
  },
  body: JSON.stringify({
    policy: 'your-policy-slug',
    model: 'hf-eleutherai-pythia-160m',
    use: 'summarisation',
    prompt,
  }),
  signal: AbortSignal.timeout(30_000),
});
const result = await res.json();
Python (requests)
import os, requests

res = requests.post(
    "https://governai.space/api/v1/route",
    headers={"authorization": f"Bearer {os.environ['GH_KEY']}"},
    json={
        "policy": "your-policy-slug",
        "model": "hf-eleutherai-pythia-160m",
        "use": "summarisation",
        "prompt": prompt,
    },
    timeout=30,
)
result = res.json()

To see a real response before you have an account, use the public demo key and the example on the router page. It is shared by everyone and capped at 20 requests a minute, so it is for looking at the shape of a response, not for testing load.

3. Handling the decision

A 200 response always carries decision, reason_codes and an audit block. Branch on decision, never on whether completion is present.
decisionWhat happenedWhat your code should do
allowThe prompt passed policy unchanged and was sent to the model you asked for.Use completion.
allow_with_redactionSomething matching a redaction rule was stripped before the model saw it. redactions.inbound lists what kind and how many — never the values.Use completion. Expect it to refer to [REDACTED:…] placeholders where the stripped text was.
rerouteThe model you asked for is not eligible under the policy, so the policy’s fallback model answered instead.Use completion. served.model names the model that actually answered; record it, not the one you requested.
require_human_reviewA review trigger matched. The model answered, but the output is withheld and queued for a person.completion is null. Keep review.ref and show “held for review”. Nothing is pushed back to your system later: a reviewer reads the output in the console and releases or rejects it there, within 72 hours, after which it is discarded. Design the workflow so the reviewer acts on a released output.
blockThe use is prohibited, the model is unknown, or it is ineligible with no fallback. No model was called.Do not retry the same request. reason_codes says why; show the user a refusal.
{
  "decision": "allow_with_redaction",
  "reason_codes": ["..."],
  "policy":   { "slug": "your-policy-slug", "min_gri": 20 },
  "requested": { "model": "hf-eleutherai-pythia-160m", "gri": 24 },
  "served":    { "model": "hf-eleutherai-pythia-160m", "gri": 24 },
  "redactions": { "inbound": [{ "key": "pan", "count": 1 }], "outbound": [] },
  "completion": "...",
  "review": null,
  "usage": { "prompt_tokens": 41, "completion_tokens": 120, "cost_usd": 0.0004, "mode": "live" },
  "spend": { "month_to_date_usd": 12.31, "budget_usd": 250 },
  "request_id": "...",
  "audit": { "seq": 1842, "entry_hash": "...", "prev_hash": "...", "prompt_sha256": "..." }
}

Store audit.seq, audit.entry_hash and request_id next to your own record of the request. They are how you, or an examiner, find the matching entry in the evidence export later.

4. When the call does not succeed

Every refusal that comes back with a status code is itself written to the audit chain, including the unauthenticated ones, so failed attempts are part of the evidence too.
Statusreason_codesMeaning
400request/invalid-json · request/missing-fieldYour request is malformed. Fix it; retrying will not help.
401auth/invalid-or-missing-keyMissing, unknown, revoked or expired key — the message is the same for all four on purpose. Check which key is deployed.
403auth/scope-missing-route · auth/cross-tenant-policyThe key lacks the route scope, or the policy belongs to another organisation.
404registry/policy-not-foundNo policy with that slug. Policy slugs are listed in your console.
413request/prompt-too-largeThe prompt is over 100,000 characters.
429quota/rate-limit-exceededOver the key’s per-minute limit. Wait retry-after seconds. x-ratelimit-limit and x-ratelimit-remaining come back on every response.
402billing/monthly-budget-exhaustedYour organisation’s monthly budget is spent. An admin raises it in the console.
timeout · 5xx · connection refusedThe service did not answer. Nothing about this request was recorded here. See “If we are unreachable” below.
If we are unreachable, fail closed. Set a timeout on the call (the examples use 30 seconds). If it times out or the service does not answer, do not fall back to calling the model provider directly: that request would leave with no policy applied and no record. Queue it, or show the user the request cannot be processed right now. A fallback that skips governance is a gap an examiner will find.

5. Keys stay on your server

  • Never put a key in a web page, a mobile app, or a code repository. The API sends no CORS headers on purpose, so a browser cannot call it directly. Call it from your backend.
  • Keep the key in your secret manager and read it from the environment at runtime.
  • Rotate a key from Keys. The old key keeps working for 24 hours so you can deploy the new one without downtime. Revoke a key the moment it may have leaked; that takes effect immediately.
  • If your network restricts outbound traffic, allow HTTPS to governai.space.

6. Collecting the evidence

A scheduled job with a key carrying the evidence scope pulls the complete audit record for a period. Give that job its own key; do not add the scope to the key your application uses.
curl -s "https://governai.space/api/v1/evidence?from=2026-08-01&to=2026-08-31&format=csv" \
  -H "authorization: Bearer $GH_EVIDENCE_KEY" -o evidence-2026-08.csv

# Is the chain intact? No key needed for the integrity result.
curl -s https://governai.space/api/v1/audit/verify

Dates are YYYY-MM-DD; without them you get the last 30 days. format is json (the default) or csv. Every record carries the exact string its hash covers, so anyone can recompute SHA-256 of it and compare it with entry_hash without using any of our code. The export also records the chain head at the moment it was taken.

7. What passes through, and what we keep

Kept

The decision, reason codes, the kinds and counts of anything redacted, the models requested and served, token counts, cost, timing, and a salted hash of the prompt. Held outputs are stored encrypted for up to 72 hours while they wait for review.

Not kept

The prompt and the model’s reply. They pass through to be checked and answered, and are not written to the log. When the router runs live, the redacted prompt is sent to the model provider to be answered.

The current limits, plainly. This service runs from a single machine behind Cloudflare, on a single database. There is no uptime commitment, no SOC 2 report, no penetration test, and no data processing agreement yet. It is suitable for evaluation and pilots, not for production traffic you cannot afford to have refused. We will tell you before any of that changes, not after.

For reviewers: the console on your phone

Held outputs expire after 72 hours, so reviewers often release them away from a desk. The console installs to a phone’s home screen like an app. No app store is involved.

iPhone and iPad

Open governai.space/console in Safari, tap Share, then Add to Home Screen. The installed app keeps its own sign-in, separate from Safari, so you sign in once more inside it. Sign in with your password and two-factor code; Google sign-in can finish in Safari instead of the app.

Android

Open governai.space/console in Chrome, open the menu, then Install app (on some phones, Add to Home screen).

Talk to the person who built this

If you got this far you are thinking about actually wiring it up. There is no sales team and no company yet — the LLC is filed and not yet approved, so this reaches one person directly. Nothing is for sale today: what is on offer is a conversation, and free early access to the method, the corpus and the router if it is useful to you. If it is not a fit, saying so costs you one reply.

Start a conversation

What are you trying to show, and to whom — an auditor, a client, a regulator, your own board?

Your address is used to reply and nothing else. It is not published, not sold, and not added to a mailing list.

Integrate — GovernanceHub