Official Python SDK for FirstHandAPI — human-in-the-loop crowdsourced data collection API
Project description
firsthandapi — FirstHandAPI Python SDK
Official Python SDK for FirstHandAPI — the human-in-the-loop (HITL) crowdsourced data collection API.
Post jobs via API. Real human workers capture photos, audio, video, and screen recordings. AI ensemble (Claude Vision + Whisper) auto-scores quality. Approved files delivered to your S3 folder. Use cases: UGC collection, ground truth for AI evaluation, LLM training data.
Installation
pip install firsthandapi
Quick Start
from firsthandapi import FirstHandClient
client = FirstHandClient(api_key="fh_live_...")
# Submit a task for human review
task = client.create_task({
"task_type": "support_reply",
"category": "text",
"input": {"customer_message": "I want a refund"},
"candidate_output": {"content": "I can help with that..."},
})
print(task["id"]) # task_01JQ...
Async Usage
import asyncio
from firsthandapi import AsyncFirstHandClient
async def main():
async with AsyncFirstHandClient(api_key="fh_live_...") as client:
task = await client.create_task({
"task_type": "support_reply",
"category": "text",
"input": {"customer_message": "I want a refund"},
"candidate_output": {"content": "I can help with that..."},
})
asyncio.run(main())
Submit and Wait
For simple workflows, submit a task and wait for the result in one call:
result = client.submit_and_wait(
{
"task_type": "support_reply",
"category": "text",
"input": {"customer_message": "I want a refund"},
"candidate_output": {"content": "I can help with that..."},
},
max_wait_seconds=120,
)
if result["status"] == "resolved":
print(result["decision"]) # approve, reject, approve_with_edit, escalate
Long Polling
Use the wait_seconds parameter to long-poll for task completion:
task = client.get_task("task_01JQ...", wait_seconds=30)
Webhook Signature Verification
from firsthandapi import verify_webhook_signature
try:
verify_webhook_signature(
payload=request.body,
signature=request.headers["X-FirstHandAPI-Signature"],
secret="whsec_...",
)
# Signature valid — process event
except ValueError as e:
# Invalid signature
print(f"Webhook verification failed: {e}")
Error Handling
from firsthandapi import FirstHandClient, FirstHandError
client = FirstHandClient(api_key="fh_live_...")
try:
task = client.create_task({"task_type": "invalid"})
except FirstHandError as e:
print(e.status) # 400
print(e.type) # "validation_error"
print(str(e)) # "Invalid task_type"
print(e.request_id) # "req_01JQ..."
Features
- Sync and async clients (
FirstHandClient/AsyncFirstHandClient) - Auto-retry with exponential backoff + jitter on 429 and 5xx errors
- Idempotency key generation on all POST requests
- Long-poll support via
Prefer: wait=Nheader - Webhook signature verification (HMAC-SHA256, timing-safe)
- Typed error hierarchy (
FirstHandError,FirstHandRateLimitError,FirstHandConnectionError)
API Methods
Tasks
create_task(body)— Submit a task for human reviewget_task(task_id)— Get task by ID (supports long-poll)list_tasks(**params)— List tasks with filtersget_task_audit(task_id)— Get audit trailcancel_task(task_id)— Cancel a pending taskvalidate_task(body)— Dry-run validationsubmit_and_wait(body)— Submit and poll until resolved
API Keys
create_api_key(body)— Create a new API keylist_api_keys()— List API keysrotate_api_key(key_id)— Rotate with 24h overlaprevoke_api_key(key_id)— Revoke immediately
Webhooks
create_webhook_endpoint(body)— Create endpointlist_webhook_endpoints()— List endpointsget_webhook_endpoint(id)— Get endpointupdate_webhook_endpoint(id, body)— Update endpointdelete_webhook_endpoint(id)— Delete endpointrotate_webhook_secret(id)— Rotate signing secret
Webhook Events
list_webhook_events()— List eventsreplay_webhook_event(id)— Replay an event
Billing
get_credit_balance()— Current credit balancelist_transactions()— Credit transaction historypurchase_credits(body)— Initiate Stripe Checkout
Quality
get_quality_summary()— Aggregate quality metrics
Organization
get_settings()— Get org settingsupdate_settings(body)— Update org settings
Requirements
- Python 3.9+
- httpx >= 0.27
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file firsthandapi-0.1.0.tar.gz.
File metadata
- Download URL: firsthandapi-0.1.0.tar.gz
- Upload date:
- Size: 7.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
72ffa9e9367be9e23b54b4d5213f49103e30c6596ab669e90e0a6acc424203f3
|
|
| MD5 |
026728a1b8472b575e974dfe82119f5e
|
|
| BLAKE2b-256 |
9b4524f49f0a7392ffd097116f162f42f5daad0204c7c3f94fc4a9a8a6732460
|
File details
Details for the file firsthandapi-0.1.0-py3-none-any.whl.
File metadata
- Download URL: firsthandapi-0.1.0-py3-none-any.whl
- Upload date:
- Size: 8.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e65ee7c8bf227a8484aab4674a77d4768f88d42eded11eb2a5d42b4ce803adb6
|
|
| MD5 |
68df6b2000acc502cf418f7ec4b5b0d1
|
|
| BLAKE2b-256 |
43657aa221169a2a192c38f27b2f17b93347df199afedde290d63113b5028ac0
|