API Reference
Everything you need to add a human checkpoint to any automation.
v1.0

Quick start

Three steps to your first verification.

1
Get your API key

Sign up at haaa.dev. Your key is available immediately — no credit card required.

2
Run your first verification
curl -X POST https://api.haaa.dev/verify \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "task": "Is this message professional enough to send to a client?",
    "content": "Hey, just checking in on that thing we discussed."
  }'
3
Handle the response

A verdict of approve means the validator confirmed it. A verdict of reject means it came back with a rejection_reason — use that to fix and retry, or route to a fallback.

// Example response
{
  "task_id": "a3f9d1c2-8b4e-4f2a-9c1d-7e6f5a4b3c2d",
  "verdict": "approve",
  "confidence": 0.94,
  "consensus": "1/1",
  "time_ms": 28400,
  "rejection_reason": null,
  "worker_ids": ["anon_a1b2c3"]
}

Authentication

Every request requires an API key passed as a Bearer token in the Authorization header.

Authorization: Bearer YOUR_API_KEY
API keys are scoped to your account. Do not expose them in client-side code or public repositories. Get your key at haaa.dev.

POST /verify

Submit a task for human verification. Returns a structured response once a validator completes the review — or the Ghost Agent handles fallback if no human claims within 90 seconds.

POST https://api.haaa.dev/verify Sync · ~60s p50

Request body

Field Type Required Description
task string required Plain-language instruction for the validator. Keep it a yes/no or approve/reject question. Max 500 characters.
content string required The agent output to be reviewed. PII is stripped automatically before any human sees it. Max 3,000 characters. Chunk longer content before calling /verify.
context string optional Additional background the validator needs. Max 500 characters.
consensus boolean optional Request two-human consensus verification with automatic tiebreaker. Default: false.

Example request

curl -X POST https://api.haaa.dev/verify \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "task": "Is this email appropriate to send to a client?",
    "content": "Hi John, following up on the invoice from last month...",
    "context": "Client is a senior executive. Formal tone required.",
    "consensus": false
  }'
import requests

response = requests.post(
    "https://api.haaa.dev/verify",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={
        "task": "Is this email appropriate to send to a client?",
        "content": agent_output,
        "context": "Formal tone required.",
        "consensus": False
    }
)

result = response.json()

if result["verdict"] == "reject":
    handle_rejection(result["rejection_reason"])
elif result["confidence"] < 0.85:
    escalate_for_review(result)
else:
    proceed_with_output()
const response = await fetch("https://api.haaa.dev/verify", {
  method: "POST",
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    task: "Is this email appropriate to send to a client?",
    content: agentOutput,
    context: "Formal tone required.",
    consensus: false,
  }),
});

const result = await response.json();

if (result.verdict === "reject") {
  handleRejection(result.rejection_reason);
} else if (result.confidence < 0.85) {
  escalateForReview(result);
} else {
  proceedWithOutput();
}
// HTTP Request node configuration
{
  "method": "POST",
  "url": "https://api.haaa.dev/verify",
  "authentication": "headerAuth",
  "body": {
    "task": "{{ $json.task_description }}",
    "content": "{{ $json.agent_output }}",
    "context": "{{ $json.context }}",
    "consensus": false
  }
}

Response

200 OK application/json
{
  "task_id":          "a3f9d1c2-8b4e-4f2a-9c1d-7e6f5a4b3c2d",
  "verdict":          "approve",   // "approve" | "reject"
  "confidence":       0.94,        // 0.0 – 1.0
  "consensus":        "1/1",       // "1/1" | "2/2" | "ghost_agent"
  "time_ms":          28400,
  "rejection_reason": null,        // string if rejected
  "worker_ids":       ["anon_a1b2c3"]
}
confidence is calculated from consensus count, worker reputation, and time-to-decision. Build conditional logic on it: if confidence < 0.85, escalate. When consensus is "ghost_agent", the AI fallback handled the task — no human was available within 90 seconds.

Response schema

Field Type Description
task_id string UUID for this verification task.
verdict string approve or reject.
confidence float 0.0–1.0. Composite of consensus count, worker reputation, and time-to-decision. Use to build conditional escalation logic.
consensus string 1/1, 2/2, or ghost_agent. Ghost agent activates at 90s if no human claims the task.
time_ms integer Total elapsed time in milliseconds from request to response. Monitor against your SLA.
rejection_reason string | null Human-provided reason when verdict is reject. Null on approve.
worker_ids array Anonymised validator identifiers. Empty array when ghost agent handled.

Error codes

HaaA uses standard HTTP status codes. All error responses follow this shape:

{
  "error": {
    "code":    "insufficient_credits",
    "message": "Your account has 0 credits remaining. Add credits at haaa.dev."
  }
}
Status Code Description
200 ok Verification complete. Check the verdict field.
400 bad_request task or content field missing or exceeds character limit.
401 unauthorized Invalid or missing API key.
402 insufficient_credits Account has no credits remaining. Top up at haaa.dev.
422 pii_blocked Content flagged by PII filter and could not be sanitised. Revise and retry.
429 rate_limited Rate limit exceeded. See rate limits.
503 unavailable No validators available and Ghost Agent fallback also unavailable. Rare. Retry after 30s.

Rate limits

Free
5
req / min
2 concurrent
Starter
20
req / min
5 concurrent
Agency Pro
60
req / min
20 concurrent
Enterprise
unlimited
unlimited

Rate limit headers are included in every response:

X-RateLimit-Limit:     60
X-RateLimit-Remaining: 47
X-RateLimit-Reset:     1709123456
SLA note: HaaA targets sub-60s response time for all human verifications. If no validator claims within 90 seconds, the Ghost Agent (AI fallback) handles the task automatically. The consensus field will read "ghost_agent" in this case. Ghost Agent responses consume credits at the standard rate.