Governance API — REST reference
This page documents the raw HTTP interface. If you work in TypeScript or JavaScript, use the SDK instead — it signs requests for you and returns typed results. Use this page when you call the API from another language, or want to see exactly what the SDK puts on the wire.
You authenticate with your GiL key (issued from your dashboard). A model-provider key is optional: send one only if you want your own Anthropic, OpenAI or Google model to answer. It is forwarded for that call and never stored.
Every account starts with the free Basic foundation, and governance is not gated by plan. Paid plans expand managed memory and workspace capacity.
Quickstart
Issue a key from your dashboard and export it as GIL_API_KEY. Each request carries a timestamp and a signature computed over the body, so a plain curl needs a few lines of shell:
export GIL_API_KEY=gil_<80 hex characters>
BODY='{"prompt":"Summarize the open decisions for this week."}'
TS=$(date +%s)
BODY_HASH=$(printf '%s' "$BODY" | openssl dgst -sha256 -hex | awk '{print $NF}')
SIG=$(printf '%s.%s' "$TS" "$BODY_HASH" \
| openssl dgst -sha256 -hmac "$GIL_API_KEY" -hex | awk '{print $NF}')
curl -X POST https://human-exe.ca/api/gil/analyze \
-H "Authorization: Bearer $GIL_API_KEY" \
-H "X-GiL-Timestamp: $TS" \
-H "X-GiL-Signature: $SIG" \
-H "Content-Type: application/json" \
--data-raw "$BODY"Never paste your GIL_API_KEY into a chat prompt, into a file an AI agent reads, or into any model context. It is a service credential, not part of the conversation.
Authentication & signing
Every request carries three headers:
Authorization: Bearer <your GiL key> X-GiL-Timestamp: <unix seconds> X-GiL-Signature: <lowercase hex HMAC-SHA256>
How the signature is built
- Serialize the body as canonical JSON: object keys sorted, no whitespace. A GET request has an empty body (an empty string).
- Hash that string with SHA-256 and write the digest as lowercase hex.
- The message to sign is
{timestamp}.{body-hash-hex}. - Compute HMAC-SHA256 of the message. The HMAC key is your whole key string (the UTF-8 bytes of
gil_…, exactly as shown at issuance). Do not decode it. - Send the result as lowercase hex in
X-GiL-Signature.
The body you send must be byte-identical to the string you hashed. If a proxy or client library reformats the JSON, the signature will not match. The SDK serializes once and reuses that exact string.
Timing and replay
- The timestamp must be within 5 minutes of server time.
- Each signed request is accepted once. Sending the exact same signed request again (same timestamp and body) returns
gil.replay_detected. Use a fresh timestamp for every request.
The key is shown once at issuance and cannot be retrieved. If you lose it, issue a new key from the dashboard, deploy it, then revoke the old one.
Endpoints
Base URL: https://human-exe.ca/api/gil
| Method | Path | Purpose |
|---|---|---|
| POST | /analyze | Governed call: prompt in, governed response and audit record out |
| GET | /usage | Per-day usage for your account |
| POST | /feedback | Report an issue or observation about the API itself |
Keys are issued and revoked from the dashboard.
POST /analyze
Submit a prompt. GiL governs it, applies session memory if you supply a session, records an audit entry, and returns the response.
Request
POST https://human-exe.ca/api/gil/analyze
X-GiL-Session: <optional session id> # reuse the same value to share session memory
{
"prompt": "…", // required
"provider": "anthropic" | "openai" | "google", // optional
"providerKey": "sk-…", // optional: your own provider key (never stored)
"model": "…", // optional
"temperature": 0.2, // optional
"max_tokens": 1024 // optional
}You do not need a provider account: provider and providerKey are optional. If you send them, your chosen provider answers and bills you directly. Send X-GiL-Session as a header (not in the body); the SDK’s sessionId option sets it for you.
Response (200)
{
"governed": true,
"session_id": "…", // pass back as X-GiL-Session to continue the session
"response": "…", // the governed answer
"v0_stub": false,
"provider": "…",
"model": "…",
"usage": {
"provider_tokens_in": 1240,
"provider_tokens_out": 512,
"gil_governance_units": 1
},
"advisories": [ { "kind": "…", "message": "…" } ],
"audit": {
"audit_id": "…",
"audit_mode": "…",
"cost_delta_pct": 0,
"coherency_score": 0.82,
"routing": "…",
"timestamp": "2026-10-09T18:00:00Z",
"decision_chain": ["…"],
"governance_state": "green",
"provenance_signature": "…" ,
"session_memory_active": true,
"drift_score": 0.0
}
}Response headers
governance-state: green | amber | red | black— see Governance stategovernance-advisory— present when the state is not greenx-request-id— quote this when you contact support
GET /usage
Per-day governance units and provider tokens for your account. Provider tokens are informational only; if you use your own provider, they are billed by that provider, not by Human.Exe.
GET https://human-exe.ca/api/gil/usage?from=2026-10-01&to=2026-10-31
Authorization: Bearer <your GiL key> # sign an empty body
{
"from": "2026-10-01",
"to": "2026-10-31",
"days": [
{ "date": "2026-10-09", "governanceUnits": 3, "providerTokensIn": 0, "providerTokensOut": 0 }
],
"total": { "governanceUnits": 3, "providerTokensIn": 0, "providerTokensOut": 0 }
}POST /feedback
Report a bug, slow response, unexpected governance result or docs gap directly to the team.
POST https://human-exe.ca/api/gil/feedback
{
"severity": "low" | "medium" | "high" | "critical", // optional
"category": "latency", // required
"message": "…", // required
"context": { }, // optional
"userFeedback": "…" // optional
}
→ { "id": "…", "status": "open", "createdAt": "…" }Governance state
Governance state never blocks your call. It controls how much of a response is visible to the calling agent. Your request always completes.
| State | Meaning | Effect on the response |
|---|---|---|
| GREEN | Healthy | Full response, full audit record. |
| AMBER | Constrained | Sensitive-looking content is masked: email addresses, long digit runs, and token-shaped strings. governance-advisory is set. |
| RED | Critical | Most of the response text is withheld. governance-advisory is set. |
| BLACK | Sealed | A placeholder is returned in place of the response. The response keeps the same shape. |
Error codes
Errors return JSON with a code and a human-readable error message. Treat an unknown code as a generic failure and rely on the HTTP status.
| HTTP | Code | Meaning |
|---|---|---|
| 400 | MISSING_PROMPT | The request had no prompt. |
| 400 | INVALID_BODY | The body was not valid JSON. |
| 400 | gil.usage.bad_range | from or to is not a valid date. |
| 401 | gil.unauthorized | Missing Authorization, or the key is not valid. |
| 401 | gil.auth.invalid | Authorization header missing or malformed. |
| 401 | gil.invalid_signature | Signature missing or does not match the request. |
| 401 | gil.invalid_timestamp | Timestamp missing, malformed, or more than 5 minutes from server time. |
| 401 | gil.replay_detected | That exact signed request was already received. Sign again with a new timestamp. |
| 401 | gil.key_revoked | The key was revoked or rotated. Create a new key from your dashboard. |
| 401 | gil.key_expired | The key has passed its expiry date. Create a new key. |
| 401 | gil.idempotency_conflict | The replay check was temporarily unavailable. Retry shortly. |
| 502 | gil.provider.failed | Your own model provider returned an error. |
| 502 / 503 | gil.governance.unavailable | The service was unreachable. Safe to retry shortly. |
| 502 | gil.usage.error | The usage lookup failed. Retry shortly. |
Skip the signing code: the SDK reference covers install, every method and error handling.