Get started with HITL.sh in under 10 minutes. Build your first human-in-the-loop application with step-by-step instructions and real-world examples.
Build your first HITL (Human-in-the-Loop) application in under 10 minutes. This tutorial walks you through creating a content moderation system where human reviewers evaluate user-generated content.
What You’ll Build: A content moderation system that automatically sends user comments to human reviewers for approval or rejection, with real-time webhook notifications.
Your loop needs human reviewers to evaluate requests. You have several options:
QR Code (Recommended)
Invite Code
Join URL
The easiest way is to share the QR code from your loop response:
Copy
import qrcodeimport requests# Get loop details with QR coderesponse = requests.get(f"{BASE_URL}/api/loops/{LOOP_ID}", headers=headers)loop_details = response.json()['data']['loop']print("📱 Share this QR code with reviewers:")print(f" QR Code URL: {loop_details['qr_code_url']}")print(f" Or share invite code: {loop_details['invite_code']}")
Reviewers scan the QR code with the HITL mobile app to join your loop.
Share the invite code directly:
Copy
print(f"🔗 Invite Code: {loop['data']['loop']['invite_code']}")print("📱 Reviewers can:")print(" 1. Download the HITL mobile app")print(" 2. Tap 'Join Loop' and enter the code")print(" 3. Start reviewing requests immediately")
Create a direct join link:
Copy
invite_code = loop['data']['loop']['invite_code']join_url = f"https://hitl.sh/join/{invite_code}"print(f"🌐 Direct Join URL: {join_url}")print(" Share this link with reviewers")
For Testing: You can proceed without reviewers for now. Later, you can test by downloading the HITL mobile app yourself and joining your loop.
Now let’s create a content moderation request. This represents user-generated content that needs human review:
Python
Node.js
cURL
Copy
# Sample user comment to moderateuser_comment = """Hey everyone! Just wanted to share my experience with this amazing product. It's been life-changing and I think you should all try it too! Check out my link in bio for a special discount. BTW, anyone who disagrees with me is totally wrong!"""# Create moderation requestrequest_data = { "loop_id": LOOP_ID, "request_text": f"Please review this user comment for community guidelines compliance:\n\n\"{user_comment}\"", "response_type": "single_select", "response_config": { "options": [ "✅ Approve - Follows guidelines", "⚠️ Approve with Warning - Minor issues", "❌ Reject - Violates guidelines", "🚨 Reject and Flag - Serious violation" ] }, "priority": "medium", "processing_type": "time-sensitive", "default_response": "❌ Reject - Review timeout", "timeout_seconds": 3600 # 1 hour}response = requests.post(f"{BASE_URL}/api/loops/{LOOP_ID}/requests", headers=headers, json=request_data)request = response.json()if response.status_code == 201: print("✅ Content moderation request created!") print(f" Request ID: {request['data']['request']['id']}") print(f" Status: {request['data']['request']['status']}") print(" 📱 Reviewers will receive this on their mobile app") REQUEST_ID = request['data']['request']['id']else: print("❌ Error creating request:", request)
Copy
async function createModerationRequest(loopId) { // Sample user comment to moderate const userComment = ` Hey everyone! Just wanted to share my experience with this amazing product. It's been life-changing and I think you should all try it too! Check out my link in bio for a special discount. BTW, anyone who disagrees with me is totally wrong! `; const requestData = { loop_id: loopId, request_text: `Please review this user comment for community guidelines compliance:\n\n"${userComment}"`, response_type: 'single_select', response_config: { options: [ '✅ Approve - Follows guidelines', '⚠️ Approve with Warning - Minor issues', '❌ Reject - Violates guidelines', '🚨 Reject and Flag - Serious violation' ] }, priority: 'medium', processing_type: 'time-sensitive', default_response: '❌ Reject - Review timeout', timeout_seconds: 3600 // 1 hour }; try { const response = await axios.post(`${BASE_URL}/api/loops/${loopId}/requests`, requestData, { headers }); const request = response.data.data.request; console.log('✅ Content moderation request created!'); console.log(` Request ID: ${request.id}`); console.log(` Status: ${request.status}`); console.log(' 📱 Reviewers will receive this on their mobile app'); return request.id; } catch (error) { console.error('❌ Error creating request:', error.response?.data || error.message); }}
Copy
# Create content moderation requestcurl -X POST https://api.hitl.sh/v1/api/loops/your_loop_id_here/requests \ -H "Authorization: Bearer your_api_key_here" \ -H "Content-Type: application/json" \ -d '{ "request_text": "Please review this user comment for community guidelines compliance:\n\nHey everyone! Just wanted to share my experience with this amazing product...", "response_type": "single_select", "response_config": { "options": [ "✅ Approve - Follows guidelines", "⚠️ Approve with Warning - Minor issues", "❌ Reject - Violates guidelines", "🚨 Reject and Flag - Serious violation" ] }, "priority": "medium", "processing_type": "time-sensitive", "default_response": "❌ Reject - Review timeout", "timeout_seconds": 3600 }'
Now that you understand the basics, consider these practical applications:
Content Moderation at Scale
Challenge: Moderate thousands of user posts per day
Solution: Create multiple specialized loops (text content, images, reported content) with different priorities and response types
Copy
# Different loops for different content typesloops = { 'text_moderation': create_loop("Text Content Review", "Review text posts and comments"), 'image_moderation': create_loop("Image Content Review", "Review uploaded images"), 'reported_content': create_loop("Reported Content", "Priority review of user-reported content")}
Data Verification
Challenge: Verify accuracy of user-submitted business information
Solution: Human reviewers check addresses, phone numbers, and business details