Official client libraries for the HumanRail API
HumanRail is an escalation layer for AI agents. When your AI hits a confidence or risk threshold, call our API to route the task to a vetted human worker pool. We verify the result, pay the worker, and return a structured response to your agent. These SDKs provide idiomatic, type-safe clients for the HumanRail API in TypeScript, Python, and Go.
Website: humanrail.dev | Documentation: docs.humanrail.dev
npm install @humanrail/sdkRequires Node.js 18+.
pip install humanrailRequires Python 3.12+.
go get github.com/prime001/humanrail-sdk/goRequires Go 1.22+.
import { HumanRailClient } from "@humanrail/sdk";
const client = new HumanRailClient({
apiKey: process.env.HUMANRAIL_API_KEY!,
});
// Create a task for human review
const task = await client.tasks.create({
idempotencyKey: "order-12345-refund-check",
taskType: "refund_eligibility",
riskTier: "medium",
slaSeconds: 300,
payload: {
orderId: "order-12345",
reason: "Item arrived damaged",
},
outputSchema: {
type: "object",
required: ["eligible", "reason"],
properties: {
eligible: { type: "boolean" },
reason: { type: "string" },
},
},
payout: { currency: "USD", maxAmount: 0.50 },
});
console.log(`Task created: ${task.id} (status: ${task.status})`);
// Poll until a human completes the task
const result = await client.tasks.waitForCompletion(task.id, {
pollIntervalMs: 2000,
timeoutMs: 600_000, // 10 minutes
});
if (result.status === "verified") {
console.log("Human verdict:", result.output);
// => { eligible: true, reason: "Damage confirmed via photo" }
} else {
console.log(`Task ended with status: ${result.status}`);
}from humanrail import HumanRailClient
client = HumanRailClient(api_key="hr_live_...")
task = client.tasks.create(
idempotency_key="order-12345-refund-check",
task_type="refund_eligibility",
payload={"orderId": "order-12345", "reason": "Item arrived damaged"},
output_schema={
"type": "object",
"required": ["eligible"],
"properties": {"eligible": {"type": "boolean"}},
},
payout={"currency": "USD", "maxAmount": 0.50},
)
result = client.tasks.wait_for_completion(task.id, timeout=600)
print(result.status, result.output)Async usage is also supported:
async with HumanRailClient(api_key="hr_live_...") as client:
task = await client.tasks.acreate(
idempotency_key="ticket-9876-classify",
task_type="ticket_classification",
payload={"subject": "Can't log in", "body": "..."},
output_schema={"type": "object", "required": ["category"]},
payout={"currency": "USD", "maxAmount": 0.25},
)
result = await client.tasks.await_for_completion(task.id)package main
import (
"context"
"fmt"
"log"
"time"
humanrail "github.com/prime001/humanrail-sdk/go/humanrail"
)
func main() {
client := humanrail.NewClient("hr_live_...",
humanrail.WithTimeout(10*time.Second),
)
ctx := context.Background()
task, err := client.CreateTask(ctx, humanrail.TaskCreateRequest{
IdempotencyKey: "order-12345-refund-check",
TaskType: "refund_eligibility",
Payload: map[string]any{"orderId": "order-12345"},
OutputSchema: map[string]any{"type": "object"},
Payout: humanrail.Payout{Currency: "USD", MaxAmount: 0.50},
})
if err != nil {
log.Fatal(err)
}
result, err := client.WaitForCompletion(ctx, task.ID, &humanrail.WaitOptions{
PollInterval: 2 * time.Second,
Timeout: 10 * time.Minute,
})
if err != nil {
log.Fatal(err)
}
fmt.Printf("Status: %s, Output: %v\n", result.Status, result.Output)
}- Typed responses -- Full type definitions in all three languages. TypeScript types, Python Pydantic models, Go structs.
- Automatic retries with backoff -- Retries on 429, 500, 502, 503, 504 with configurable exponential, linear, or fixed backoff.
- Idempotency support -- Every mutating request accepts an
idempotency_key. A built-ingenerateIdempotencyKeyhelper produces deterministic SHA-256 keys from a namespace and parts. - Webhook signature verification -- HMAC-SHA256 signature checking with timestamp tolerance to prevent replay attacks.
- OpenTelemetry tracing -- Instrumentation hooks for distributed tracing across your agent pipeline.
- Polling and webhooks -- Use
waitForCompletionfor simple polling, or configure webhook endpoints for event-driven workflows. - Async support -- The Python SDK provides both synchronous and asynchronous interfaces. The Go SDK uses context-based cancellation.
HumanRail signs every webhook payload with HMAC-SHA256. The signature header (X-HumanRail-Signature) has the format:
t=<unix-timestamp>,v1=<hex-hmac>
The signed content is <timestamp>.<raw-body>. Always verify signatures before processing webhook events.
import { verifyWebhookSignature } from "@humanrail/sdk";
app.post("/webhooks/humanrail", (req, res) => {
const isValid = verifyWebhookSignature({
payload: req.body, // raw body string
signature: req.headers["x-humanrail-signature"],
secret: process.env.HUMANRAIL_WEBHOOK_SECRET!,
tolerance: 300, // reject if older than 5 minutes
});
if (!isValid) {
return res.status(401).send("Invalid signature");
}
const event = JSON.parse(req.body);
// Handle event.type: "task.verified", "task.failed", etc.
res.status(200).send("OK");
});from humanrail import verify_webhook_signature
@app.post("/webhooks/humanrail")
def handle_webhook(request):
is_valid = verify_webhook_signature(
payload=request.body.decode(),
signature=request.headers["X-HumanRail-Signature"],
secret=WEBHOOK_SECRET,
tolerance=300,
)
if not is_valid:
return Response(status_code=401)
event = request.json()
# Handle event["type"]: "task.verified", "task.failed", etc.
return Response(status_code=200)import "github.com/prime001/humanrail-sdk/go/humanrail"
func webhookHandler(w http.ResponseWriter, r *http.Request) {
body, _ := io.ReadAll(r.Body)
valid := humanrail.VerifyWebhookSignature(humanrail.WebhookVerifyParams{
Payload: string(body),
Signature: r.Header.Get("X-HumanRail-Signature"),
Secret: os.Getenv("HUMANRAIL_WEBHOOK_SECRET"),
Tolerance: 300,
})
if !valid {
http.Error(w, "Invalid signature", http.StatusUnauthorized)
return
}
// Parse and handle event
w.WriteHeader(http.StatusOK)
}| Language | Package | Docs |
|---|---|---|
| TypeScript | @humanrail/sdk | docs.humanrail.dev/sdk/typescript |
| Python | humanrail | docs.humanrail.dev/sdk/python |
| Go | github.com/prime001/humanrail-sdk/go | docs.humanrail.dev/sdk/go |
The full API reference is available at docs.humanrail.dev/api. The OpenAPI 3.1 spec is included in the openapi/ directory of this repository.
Contributions are welcome. Please read CONTRIBUTING.md before submitting a pull request.
To get started:
- Fork the repository.
- Create a feature branch from
main. - Make your changes and add tests.
- Open a pull request with a clear description of the change.
Bug reports and feature requests can be filed via GitHub Issues.
This project is licensed under the MIT License.
For questions, support, or partnership inquiries: [email protected]