Official client libraries for TypeScript, Python, and Go. All SDKs are open source (MIT licensed), fully typed, and include built-in retry logic and webhook signature verification.
@humanrail/sdk on npm. Full TypeScript types, ESM and CJS.
humanrail on PyPI. Async/sync clients, Pydantic models.
github.com/humanrail/humanrail-go. Idiomatic Go, context support.
npm install @humanrail/sdk
# or
pnpm add @humanrail/sdk
# or
yarn add @humanrail/sdk
import { HumanRail } from "@humanrail/sdk";
const client = new HumanRail({
apiKey: process.env.HUMANRAIL_API_KEY,
});
// Create a task
const task = await client.tasks.create({
idempotencyKey: "unique-key",
taskType: "content_moderation",
slaSeconds: 600,
payload: { contentUrl: "https://example.com/post/123" },
outputSchema: { type: "object", properties: { safe: { type: "boolean" } } },
payout: { currency: "USD", maxAmount: 0.25 },
});
// Get a task
const result = await client.tasks.get(task.id);
// List tasks
const list = await client.tasks.list({ status: "verified", limit: 10 });
// Cancel a task
await client.tasks.cancel(task.id);
// Verify a webhook signature
import { verifyWebhookSignature } from "@humanrail/sdk";
const isValid = verifyWebhookSignature({
payload: rawBody,
signature: req.headers["x-escalation-signature"],
secret: process.env.HUMANRAIL_WEBHOOK_SECRET,
});
idempotencyKey on create, the SDK handles the headerverifyWebhookSignature() with timestamp tolerance checkpip install humanrail
# or with uv
uv add humanrail
import os
from humanrail import HumanRail
client = HumanRail(api_key=os.environ["HUMANRAIL_API_KEY"])
# Create a task
task = client.tasks.create(
idempotency_key="unique-key",
task_type="content_moderation",
sla_seconds=600,
payload={"contentUrl": "https://example.com/post/123"},
output_schema={"type": "object", "properties": {"safe": {"type": "boolean"}}},
payout={"currency": "USD", "maxAmount": 0.25},
)
# Get a task
result = client.tasks.get(task.id)
# List tasks
tasks = client.tasks.list(status="verified", limit=10)
# Cancel a task
client.tasks.cancel(task.id)
# Async client
from humanrail import AsyncHumanRail
async_client = AsyncHumanRail(api_key=os.environ["HUMANRAIL_API_KEY"])
task = await async_client.tasks.create(...)
HumanRail for synchronous, AsyncHumanRail for async/awaitverify_webhook_signature() utility with timestamp tolerancego get github.com/humanrail/humanrail-go
package main
import (
"context"
"fmt"
"os"
"github.com/humanrail/humanrail-go"
)
func main() {
client := humanrail.NewClient(os.Getenv("HUMANRAIL_API_KEY"))
ctx := context.Background()
// Create a task
task, err := client.Tasks.Create(ctx, &humanrail.TaskCreateParams{
IdempotencyKey: "unique-key",
TaskType: "content_moderation",
SLASeconds: 600,
Payload: map[string]any{
"contentUrl": "https://example.com/post/123",
},
OutputSchema: map[string]any{
"type": "object",
"properties": map[string]any{
"safe": map[string]any{"type": "boolean"},
},
},
Payout: &humanrail.Payout{Currency: "USD", MaxAmount: 0.25},
})
if err != nil {
panic(err)
}
// Get a task
result, _ := client.Tasks.Get(ctx, task.ID)
fmt.Println(result.Status)
// Verify a webhook
isValid := humanrail.VerifyWebhookSignature(body, signature, secret)
}
context.Context on all methodsVerifyWebhookSignature() with constant-time comparisonView on GitHub · View on pkg.go.dev
All SDKs automatically retry requests that receive a 429 Too Many Requests
or 5xx server error response. The retry behavior is configurable:
| Setting | Default | Description |
|---|---|---|
maxRetries |
3 |
Maximum number of retry attempts |
retryDelay |
500ms |
Initial delay before first retry |
maxRetryDelay |
30s |
Maximum delay between retries |
When a 429 response includes a Retry-After header, the SDK
honors it instead of using the calculated backoff delay.
When you pass an idempotencyKey to tasks.create(), the SDK
automatically sets the Idempotency-Key header. If the server returns a
200 (idempotent replay), the SDK returns the existing task without error.
All SDKs raise typed errors that map to the API's error types. You can catch specific error types to handle different failure modes:
import { HumanRailError, RateLimitError, ValidationError } from "@humanrail/sdk";
try {
const task = await client.tasks.create({ ... });
} catch (err) {
if (err instanceof ValidationError) {
console.error("Invalid request:", err.details);
} else if (err instanceof RateLimitError) {
console.error("Rate limited. Retry after:", err.retryAfter);
} else if (err instanceof HumanRailError) {
console.error("API error:", err.type, err.message);
}
}
The HumanRail CLI provides command-line access to the API, useful for scripting, CI/CD pipelines, and local development.
# Install
npm install -g @humanrail/cli
# Configure
humanrail auth login
# Create a task
humanrail tasks create \
--type refund_eligibility \
--risk-tier medium \
--sla 300 \
--payload '{"orderId": "order-123"}' \
--output-schema '{"type": "object", "properties": {"eligible": {"type": "boolean"}}}' \
--payout-currency USD \
--payout-amount 0.50
# Get a task
humanrail tasks get tsk_01abc123
# List tasks
humanrail tasks list --status verified --limit 5
# Listen for webhooks locally
humanrail webhooks listen --forward-to http://localhost:3000/webhooks