← Back to humanlayer.systems
FR | EN

API HumanLayer v1.0

Integrate qualified human decisions into your AI agents via a simple REST API. Submit, track and receive structured verdicts in just a few lines of code.

Arbitrium is exposed as an escalation state in the system. Your agent runs automated by default, then HumanLayer routes to the right Sentinel once the threshold is reached.

Authentication

All agent requests must include your API key in the x-api-key header.

Header
x-api-key: hl_your_api_key
💡 How to get your key Contact the HumanLayer team at humanlayer@in6.ai to receive your API credentials.

Base URL: https://humanlayer.systems/.netlify/functions

Decision Flow

The complete lifecycle of a decision request:

🤖
AI Agent
Submits the request
HumanLayer API
Routes to a Sentinel
👤
Sentinel
Reviews and decides
Decision
Verdict + reasoning
  1. The agent submits a decision request via POST /ai-request.
  2. When the Arbitrium threshold is reached, the API assigns a qualified Sentinel automatically.
  3. The Sentinel reviews the case and renders a verdict (approved / rejected / escalated).
  4. The agent retrieves the decision via GET /ai-request?id=xxx.

What your system gets back

  • request_id and lifecycle state (pending, assigned, decided)
  • verdict and reasoning
  • signed_at decision timestamp
  • an audit-ready evidence artifact

Submit a Request

POST /ai-request

Creates a new human decision request. The API attempts to automatically assign a qualified Sentinel.

Request Body (JSON)

Parameter Type Required Description
agent_id string required Unique identifier for your agent
agent_name string optional Human-readable agent name (e.g. "QuoteBot Agent")
request_type string required compliance | judgment | signature | conformité | jugement
domain string required Expertise domain: legal, finance, compliance, medical, etc.
jurisdiction string optional Applicable jurisdiction (e.g. "Québec", "France", "EU")
summary string required Clear summary of the decision request
context_json object optional Structured context (supporting documents, data, etc.)
priority string optional normal (default) | urgent
expires_at ISO 8601 optional Expiration date (default: 48h)
callback_url string optional Webhook URL — will receive a POST with the verdict as soon as the Sentinel decides

Response (200)

json
{ "ok": true, "request_id": "a1b2c3d4-e5f6-...", "status": "assigned", "assigned_to": "Marie Dupont" }
⚠️ Status "pending" If no qualified Sentinel is available, the status will be pending instead of assigned. The request remains in the queue until a matching Sentinel is activated.

Check Status

GET /ai-request?id={request_id}

Poll the status of a specific request. Use this endpoint in a loop to wait for the Sentinel's decision.

Response (200) — pending

json
{ "request": { "id": "a1b2c3d4-...", "status": "assigned", "agent_id": "my-agent", "summary": "Validate this contract...", "verdict": null, "reasoning": null } }

Response (200) — decided

json
{ "request": { "id": "a1b2c3d4-...", "status": "decided", "verdict": "approved", "reasoning": "The contract complies with Bill 25 standards. No problematic clauses identified.", "decision_signed_at": "2026-02-14T16:30:00.000Z" } }

List Requests

GET /ai-request?agent_id={agent_id}

Retrieve all requests submitted by an agent, sorted by date descending (max 100).

Response (200)

json
{ "requests": [ { "id": "...", "status": "decided", "verdict": "approved", ... }, { "id": "...", "status": "assigned", "verdict": null, ... } ] }

Code Examples

curl — Submit a request

bash
curl -X POST https://humanlayer.systems/.netlify/functions/ai-request \ -H "Content-Type: application/json" \ -H "x-api-key: hl_your_key" \ -d '{ "agent_id": "my-agent", "agent_name": "QuoteBot Agent", "request_type": "compliance", "domain": "legal", "jurisdiction": "Québec", "summary": "Validate Bill 25 compliance for this service contract", "context_json": { "contract_id": "CTR-2026-0412", "amount": 50000, "parties": ["Acme Corp", "Client XYZ"] }, "priority": "normal" }'

curl — Check status

bash
curl https://humanlayer.systems/.netlify/functions/ai-request?id=a1b2c3d4-... \ -H "x-api-key: hl_your_key"

JavaScript / Node.js — Full flow

javascript
const API = 'https://humanlayer.systems/.netlify/functions'; const API_KEY = process.env.HUMANLAYER_API_KEY; // 1. Submit a request async function requestDecision(summary, domain, context) { const res = await fetch(`${API}/ai-request`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'x-api-key': API_KEY }, body: JSON.stringify({ agent_id: 'my-agent', request_type: 'compliance', domain, summary, context_json: context }) }); return await res.json(); } // 2. Wait for decision (polling) async function waitForDecision(requestId, intervalMs = 15000) { while (true) { const res = await fetch( `${API}/ai-request?id=${requestId}`, { headers: { 'x-api-key': API_KEY } } ); const { request } = await res.json(); if (request.status === 'decided') { return { verdict: request.verdict, reasoning: request.reasoning }; } await new Promise(r => setTimeout(r, intervalMs)); } } // 3. Usage const { request_id } = await requestDecision( 'Validate compliance on this contract', 'legal', { contract_id: 'CTR-2026-0412' } ); const decision = await waitForDecision(request_id); console.log(decision); // { verdict: "approved", reasoning: "Bill 25 compliant..." }

Python — Full flow

python
import requests, time, os API = "https://humanlayer.systems/.netlify/functions" HEADERS = { "Content-Type": "application/json", "x-api-key": os.environ["HUMANLAYER_API_KEY"] } # 1. Submit a request resp = requests.post(f"{API}/ai-request", headers=HEADERS, json={ "agent_id": "my-python-agent", "request_type": "compliance", "domain": "legal", "summary": "Validate compliance on this contract", "context_json": {"contract_id": "CTR-2026-0412"} }) request_id = resp.json()["request_id"] # 2. Wait for decision while True: r = requests.get( f"{API}/ai-request", params={"id": request_id}, headers=HEADERS ) data = r.json()["request"] if data["status"] == "decided": print(f"Verdict: {data['verdict']}") print(f"Reasoning: {data['reasoning']}") break time.sleep(15)

Request Statuses

Status Description
pending Awaiting assignment — no qualified Sentinel available
assigned Assigned to a Sentinel — under review
decided Verdict rendered — verdict and reasoning available

Possible Verdicts

  • approved — The request is approved by the Sentinel
  • rejected — The request is rejected with justification
  • escalated — Escalated for additional review

Error Handling

Code Meaning Action
400 Missing fields or invalid request type Check the JSON body
401 Invalid or missing API key Check the x-api-key header
404 Request not found Check the request_id
500 Server error Retry after a few seconds

All errors return a JSON object with an error field:

json
{ "error": "Missing fields: agent_id, summary" }

Webhook (callback)

Instead of polling in a loop, provide a callback_url in your POST request. As soon as the Sentinel renders a verdict, HumanLayer will send a POST to that URL:

json — webhook payload
{ "event": "decision.rendered", "request_id": "a1b2c3d4-...", "verdict": "approved", "reasoning": "Compliant with standards...", "signed_at": "2026-02-14T16:30:00.000Z", "sentinel_name": "Marie Dupont" }
✓ Recommended for production Webhooks are more efficient than polling: instant response with no unnecessary network traffic.