Skip to main content

Requests Introduction

Requests are the fundamental building blocks of HITL.sh workflows. They represent pieces of content, decisions, or actions that require human oversight before proceeding. Understanding how to create and structure requests is essential for building effective human-in-the-loop systems.

What are Requests?

A request in HITL.sh is a structured data package that contains:
  • Content to Review: The actual material requiring human oversight
  • Context Information: Background data to help reviewers make decisions
  • AI Analysis: Results from your AI system’s initial processing
  • Metadata: Request details like priority, source, and timestamps
  • Routing Instructions: How the request should be handled

Request Examples

  • Flagged social media posts for content moderation
  • Suspicious financial transactions for fraud review
  • AI-generated content for quality assurance
  • Customer support tickets requiring escalation
  • Compliance documents for verification

Request Lifecycle

Requests follow a straightforward lifecycle from creation to completion:

1. Creation

Your application creates a request using the API, specifying the content type, response requirements, and reviewer instructions:
import requests

# Create the request
request_data = {
    "processing_type": "time-sensitive",
    "type": "markdown", 
    "priority": "high",
    "request_text": "Review this comment: 'Great product! Use my referral code SAVE20.'",
    "response_type": "single_select",
    "response_config": {
        "options": [
            {"value": "approve", "label": "✅ Approve", "color": "#22c55e"},
            {"value": "reject", "label": "❌ Reject", "color": "#ef4444"}
        ],
        "required": True
    },
    "default_response": "reject",
    "timeout_seconds": 3600,
    "platform": "api"
}

response = requests.post(
    f"https://api.hitl.sh/v1/api/loops/{loop_id}/requests",
    headers={"Authorization": f"Bearer {api_key}"},
    json=request_data
)

request_id = response.json()["data"]["request_id"]

2. Broadcasting

The API immediately sends push notifications to all active members of the target loop. Members receive the request in their mobile app with priority-based ordering.

3. Pending

The request waits in the queue for a reviewer to claim it. Requests are ordered by priority (critical → high → medium → low) and creation time.

4. Claimed

When a reviewer opens the request in their mobile app, it’s marked as “claimed” and removed from other reviewers’ queues to prevent duplicate work.

5. Completed

The reviewer submits their response using the configured response type. The request status changes to “completed” and the response data becomes available via the API.

6. Webhook (Optional)

If you configured a callback_url, HITL.sh sends a webhook notification with the response data to your endpoint.

Retrieving the Response

# Poll for the completed response
def get_response(request_id):
    response = requests.get(
        f"https://api.hitl.sh/v1/api/requests/{request_id}",
        headers={"Authorization": f"Bearer {api_key}"}
    )
    
    if response.status_code == 200:
        data = response.json()["data"]["request"]
        
        if data["status"] == "completed":
            # Process the human response
            response_data = data["response_data"]
            
            if data["response_type"] == "single_select":
                decision = response_data["selected_value"]
                if decision == "approve":
                    approve_content()
                elif decision == "reject":
                    reject_content()
                    
        elif data["status"] == "timeout":
            # Handle timeout using default response
            default_response = data["default_response"]
            handle_timeout_response(default_response)
            
        return data
    
    return None

Request Content Types

HITL.sh supports two content types for human review:

Markdown Requests

Review text-based content like comments, posts, articles, or documents formatted in markdown

Image Requests

Review visual content like photos, graphics, or screenshots requiring human evaluation

Markdown Content Type

Use type: "markdown" for text-based content review:
request_data = {
    "type": "markdown",
    "request_text": "Please review this user comment: 'Great product! I've been using it for 6 months and highly recommend it.'",
    "response_type": "single_select",
    "response_config": {
        "options": [
            {"value": "approve", "label": "✅ Approve", "color": "#22c55e"},
            {"value": "reject", "label": "❌ Reject", "color": "#ef4444"}
        ]
    }
}

Image Content Type

Use type: "image" for visual content review:
request_data = {
    "type": "image", 
    "request_text": "Review this uploaded profile photo for appropriateness",
    "image_url": "https://example.com/uploads/profile_123.jpg",
    "response_type": "boolean",
    "response_config": {
        "true_label": "✅ Appropriate",
        "false_label": "❌ Inappropriate"
    }
}

Request Structure

Required Fields

Every request must include these essential elements:
{
  "processing_type": "time-sensitive|deferred",
  "type": "markdown|image",
  "priority": "low|medium|high|critical",
  "request_text": "string",
  "response_type": "text|single_select|multi_select|rating|number|boolean",
  "response_config": "object",
  "default_response": "varies by response_type"
}

Optional Fields

Enhance requests with additional context and configuration:
{
  "image_url": "https://example.com/image.jpg",
  "context": {
    "user_id": "user_123", 
    "post_id": "post_456",
    "automated_flags": ["potential_spam"],
    "previous_violations": 2
  },
  "timeout_seconds": 3600,
  "callback_url": "https://example.com/webhook/response",
  "platform": "api",
  "platform_version": "1.0.0"
}

Request Priority Levels

Low Priority

Standard requests with no time sensitivity:
  • Response Time: 24-48 hours
  • Reviewer Level: Any available reviewer
  • Examples: General content moderation, routine quality checks

Medium Priority

Standard business requests:
  • Response Time: 4-8 hours
  • Reviewer Level: Standard reviewers
  • Examples: Content approval, user reports, policy reviews

High Priority

Time-sensitive requests requiring prompt attention:
  • Response Time: 1-2 hours
  • Reviewer Level: Experienced reviewers
  • Examples: Customer escalations, urgent compliance reviews

Critical Priority

Critical requests requiring immediate attention:
  • Response Time: 15-30 minutes
  • Reviewer Level: Senior reviewers or escalation team
  • Examples: Security incidents, legal compliance issues, emergency reviews

Request States

Track the progress of requests through their lifecycle:

Pending

Request is waiting to be assigned to a reviewer.

Assigned

Request has been assigned to a specific reviewer.

In Review

Reviewer is actively examining the request.

Completed

Human decision has been made and returned.

Escalated

Request has been escalated to a senior reviewer.

Timed Out

Request exceeded response time and was auto-processed.

Creating Effective Requests

Content Presentation

1

Clear Formatting

Present content in a format that’s easy for reviewers to understand.
2

Relevant Context

Include all information reviewers need to make informed decisions.
3

Structured Data

Organize request data logically with consistent formatting.
4

Appropriate Priority

Set realistic priorities based on business impact and urgency.

AI Analysis Integration

Confidence Scores

Include AI confidence levels to help reviewers understand uncertainty.

Flagged Issues

Highlight specific concerns the AI has identified.

Risk Assessment

Provide risk scores and reasoning for human consideration.

Model Information

Include AI model version and processing details for transparency.

Request Performance

Metrics to Track

Monitor request performance to optimize your workflows:
  • Average response time per request type
  • 95th percentile response times
  • Time to first response
  • Escalation frequency and timing
  • Decision consistency across reviewers
  • Inter-rater reliability scores
  • Error rates and types
  • Reviewer performance trends
  • Requests per day/week/month
  • Peak load times and patterns
  • Queue length and processing capacity
  • Loop utilization rates

Optimization Strategies

1

Batch Processing

Group similar requests to reduce reviewer overhead.
2

Smart Routing

Route requests to reviewers with appropriate expertise.
3

Load Balancing

Distribute requests evenly across your reviewer team.
4

Priority Queuing

Process high-priority requests before lower-priority ones.

Best Practices

Request Design

Clear Content

Present content in a format that’s easy for reviewers to understand.

Relevant Context

Include all information reviewers need to make informed decisions.

Structured Data

Organize request data logically with consistent formatting.

Appropriate Priority

Set realistic priorities based on business impact and urgency.

Performance Optimization

  • Validation: Verify request data before submission
  • Consistency: Maintain consistent request structure across loops
  • Monitoring: Track request processing times and success rates
  • Feedback: Use reviewer feedback to improve request quality

Complete Examples

Content Moderation (Markdown)

Review text content for community guidelines:
import requests

# Create a markdown content review request
request_data = {
    "processing_type": "time-sensitive",
    "type": "markdown", 
    "priority": "high",
    "request_text": "Review this user comment for community guidelines: 'This product is amazing! Everyone should try it. Use code SAVE20 for discount.'",
    "context": {
        "user_id": "user_12345",
        "comment_id": "comment_789",
        "automated_flags": ["promotional_content"]
    },
    "timeout_seconds": 1800,
    "response_type": "single_select",
    "response_config": {
        "options": [
            {"value": "approve", "label": "✅ Approve", "color": "#22c55e"},
            {"value": "reject", "label": "❌ Reject", "color": "#ef4444"},
            {"value": "edit", "label": "✏️ Needs Editing", "color": "#f59e0b"}
        ],
        "required": True
    },
    "default_response": "reject",
    "platform": "api"
}

response = requests.post(
    f"https://api.hitl.sh/v1/api/loops/{loop_id}/requests",
    headers={"Authorization": f"Bearer {api_key}"},
    json=request_data
)

Image Moderation

Review visual content for appropriateness:
# Create an image review request
request_data = {
    "processing_type": "time-sensitive",
    "type": "image",
    "priority": "high", 
    "request_text": "Review this uploaded profile photo for appropriateness and compliance with our image guidelines.",
    "image_url": "https://cdn.example.com/uploads/profile_photos/user_12345.jpg",
    "context": {
        "user_id": "user_12345",
        "upload_timestamp": "2024-01-15T10:30:00Z",
        "file_size": "2.4MB"
    },
    "timeout_seconds": 900,
    "response_type": "boolean",
    "response_config": {
        "true_label": "✅ Approve Image",
        "false_label": "❌ Reject Image",
        "true_color": "#22c55e",
        "false_color": "#ef4444",
        "required": True
    },
    "default_response": False,  # Conservative default
    "platform": "api"
}

response = requests.post(
    f"https://api.hitl.sh/v1/api/loops/{loop_id}/requests", 
    headers={"Authorization": f"Bearer {api_key}"},
    json=request_data
)

Retrieving Responses

def get_request_status(request_id):
    response = requests.get(
        f"https://api.hitl.sh/v1/api/requests/{request_id}",
        headers={"Authorization": f"Bearer {api_key}"}
    )
    
    if response.status_code == 200:
        data = response.json()["data"]["request"]
        
        if data["status"] == "completed":
            return {
                "completed": True,
                "response_data": data["response_data"],
                "response_by": data["response_by_user"]["name"],
                "completion_time": data["completed_at"]
            }
        else:
            return {
                "completed": False,
                "status": data["status"],
                "timeout_at": data.get("timeout_at")
            }
    
    return None

Next Steps

Ready to start creating requests for your loops?
I