GET
/
v1
/
requests
# Get all requests
curl -X GET https://api.hitl.sh/v1/requests \
  -H "Authorization: Bearer your_api_key_here"

# Get pending requests only
curl -X GET "https://api.hitl.sh/v1/requests?status=pending" \
  -H "Authorization: Bearer your_api_key_here"

# Get high priority requests with pagination
curl -X GET "https://api.hitl.sh/v1/requests?priority=high&limit=20&offset=0" \
  -H "Authorization: Bearer your_api_key_here"
{
  "error": false,
  "msg": "Requests retrieved successfully",
  "data": {
    "requests": [
      {
        "id": "65f1234567890abcdef12348",
        "loop_id": "65f1234567890abcdef12345",
        "processing_type": "time-sensitive",
        "type": "markdown",
        "priority": "high",
        "request_text": "Please review this user-generated content for community guidelines compliance.",
        "response_type": "single_select",
        "status": "completed",
        "response_data": "Approve",
        "response_by": "65f1234567890abcdef12350",
        "response_at": "2024-03-15T10:45:00Z",
        "response_time_seconds": 900.5,
        "timeout_at": "2024-03-15T11:30:00Z",
        "created_at": "2024-03-15T10:30:00Z",
        "updated_at": "2024-03-15T10:45:00Z"
      },
      {
        "id": "65f1234567890abcdef12349",
        "loop_id": "65f1234567890abcdef12345",
        "processing_type": "deferred",
        "type": "markdown",
        "priority": "medium",
        "request_text": "Rate the quality of this AI-generated response for accuracy and helpfulness.",
        "response_type": "rating",
        "status": "pending",
        "response_data": null,
        "response_by": null,
        "response_at": null,
        "response_time_seconds": null,
        "timeout_at": "2024-04-14T10:30:00Z",
        "created_at": "2024-03-15T10:35:00Z",
        "updated_at": "2024-03-15T10:35:00Z"
      }
    ],
    "count": 2,
    "total": 15,
    "has_more": true,
    "pagination": {
      "limit": 50,
      "offset": 0,
      "next_offset": 50
    }
  }
}
Get a comprehensive list of all requests you’ve created using your API key. This endpoint provides detailed information about each request including current status, response data, and performance metrics.

Authentication

Authorization
string
required
Your API key for authentication

Query Parameters

status
string
Filter requests by status
Options: pending, claimed, completed, timeout, cancelled
priority
string
Filter requests by priority level
Options: low, medium, high, critical
loop_id
string
Filter requests from a specific loop
limit
integer
Maximum number of requests to return (1-100, default: 50)
offset
integer
Number of requests to skip for pagination (default: 0)
sort
string
Sort order for results
Options: created_at_desc (default), created_at_asc, priority_desc, status_asc

Response

error
boolean
Whether an error occurred
msg
string
Success message
data
object
# Get all requests
curl -X GET https://api.hitl.sh/v1/requests \
  -H "Authorization: Bearer your_api_key_here"

# Get pending requests only
curl -X GET "https://api.hitl.sh/v1/requests?status=pending" \
  -H "Authorization: Bearer your_api_key_here"

# Get high priority requests with pagination
curl -X GET "https://api.hitl.sh/v1/requests?priority=high&limit=20&offset=0" \
  -H "Authorization: Bearer your_api_key_here"
{
  "error": false,
  "msg": "Requests retrieved successfully",
  "data": {
    "requests": [
      {
        "id": "65f1234567890abcdef12348",
        "loop_id": "65f1234567890abcdef12345",
        "processing_type": "time-sensitive",
        "type": "markdown",
        "priority": "high",
        "request_text": "Please review this user-generated content for community guidelines compliance.",
        "response_type": "single_select",
        "status": "completed",
        "response_data": "Approve",
        "response_by": "65f1234567890abcdef12350",
        "response_at": "2024-03-15T10:45:00Z",
        "response_time_seconds": 900.5,
        "timeout_at": "2024-03-15T11:30:00Z",
        "created_at": "2024-03-15T10:30:00Z",
        "updated_at": "2024-03-15T10:45:00Z"
      },
      {
        "id": "65f1234567890abcdef12349",
        "loop_id": "65f1234567890abcdef12345",
        "processing_type": "deferred",
        "type": "markdown",
        "priority": "medium",
        "request_text": "Rate the quality of this AI-generated response for accuracy and helpfulness.",
        "response_type": "rating",
        "status": "pending",
        "response_data": null,
        "response_by": null,
        "response_at": null,
        "response_time_seconds": null,
        "timeout_at": "2024-04-14T10:30:00Z",
        "created_at": "2024-03-15T10:35:00Z",
        "updated_at": "2024-03-15T10:35:00Z"
      }
    ],
    "count": 2,
    "total": 15,
    "has_more": true,
    "pagination": {
      "limit": 50,
      "offset": 0,
      "next_offset": 50
    }
  }
}

Request Status Overview

Pending

Status: pending
  • Waiting for reviewer to claim
  • No response yet
  • Can be cancelled

Claimed

Status: claimed
  • Reviewer is working on it
  • Response expected soon
  • Cannot be cancelled

Completed

Status: completed
  • Reviewer submitted response
  • response_data contains the answer
  • Can receive feedback

Timeout

Status: timeout
  • Request exceeded timeout period
  • default_response used as final answer
  • No further action possible

Cancelled

Status: cancelled
  • Request was cancelled before completion
  • No response data available
  • Final status

Filtering and Sorting

Advanced Filtering Examples

def get_requests_dashboard():
    """Get comprehensive request dashboard data"""
    api_key = "your_api_key_here"
    headers = {"Authorization": f"Bearer {api_key}"}
    base_url = "https://api.hitl.sh/v1/requests"
    
    dashboard_data = {}
    
    # Get requests by status
    statuses = ["pending", "claimed", "completed", "timeout", "cancelled"]
    for status in statuses:
        response = requests.get(f"{base_url}?status={status}", headers=headers)
        data = response.json()["data"]
        dashboard_data[f"{status}_requests"] = {
            "count": data["total"],
            "requests": data["requests"][:5]  # First 5 for preview
        }
    
    # Get high priority pending requests
    urgent_response = requests.get(
        f"{base_url}?status=pending&priority=high&sort=created_at_asc", 
        headers=headers
    )
    dashboard_data["urgent_pending"] = urgent_response.json()["data"]["requests"]
    
    # Get recent completions
    recent_response = requests.get(
        f"{base_url}?status=completed&sort=created_at_desc&limit=10", 
        headers=headers
    )
    dashboard_data["recent_completions"] = recent_response.json()["data"]["requests"]
    
    return dashboard_data

Pagination Best Practices

Efficient Pagination

Handle large datasets efficiently:
def paginate_all_requests(api_key, batch_size=100):
    """Generator that yields all requests in batches"""
    headers = {"Authorization": f"Bearer {api_key}"}
    url = "https://api.hitl.sh/v1/requests"
    offset = 0
    
    while True:
        params = {"limit": batch_size, "offset": offset}
        response = requests.get(url, headers=headers, params=params)
        data = response.json()["data"]
        
        # Yield current batch
        for request in data["requests"]:
            yield request
        
        # Check if we have more data
        if not data["has_more"]:
            break
            
        offset += batch_size

# Usage
request_count = 0
for request in paginate_all_requests("your_api_key"):
    request_count += 1
    if request["status"] == "pending":
        print(f"Pending request: {request['id']}")

print(f"Total requests processed: {request_count}")

Cursor-based Pagination (Alternative)

For very large datasets, implement cursor-based pagination:
class RequestsPaginator {
    constructor(apiKey, filters = {}) {
        this.apiKey = apiKey;
        this.filters = filters;
        this.lastCreatedAt = null;
    }
    
    async getNextPage(limit = 50) {
        const params = new URLSearchParams();
        params.append('limit', limit);
        params.append('sort', 'created_at_desc');
        
        // Add filters
        Object.keys(this.filters).forEach(key => {
            if (this.filters[key]) {
                params.append(key, this.filters[key]);
            }
        });
        
        // Cursor pagination using created_at
        if (this.lastCreatedAt) {
            params.append('created_before', this.lastCreatedAt);
        }
        
        const response = await axios.get(
            `https://api.hitl.sh/v1/requests?${params}`,
            { headers: { 'Authorization': `Bearer ${this.apiKey}` } }
        );
        
        const requests = response.data.data.requests;
        
        if (requests.length > 0) {
            this.lastCreatedAt = requests[requests.length - 1].created_at;
        }
        
        return {
            requests,
            hasMore: requests.length === limit
        };
    }
}

Request Performance Analysis

Response Time Analysis

Analyze reviewer performance:
def analyze_response_times(requests_data):
    """Analyze response time patterns"""
    completed_requests = [r for r in requests_data if r["status"] == "completed" and r["response_time_seconds"]]
    
    if not completed_requests:
        return {"error": "No completed requests with response times"}
    
    response_times = [r["response_time_seconds"] for r in completed_requests]
    
    analysis = {
        "total_completed": len(completed_requests),
        "avg_response_time_seconds": sum(response_times) / len(response_times),
        "min_response_time": min(response_times),
        "max_response_time": max(response_times),
        "median_response_time": sorted(response_times)[len(response_times) // 2],
        "response_time_ranges": {
            "under_5_min": sum(1 for t in response_times if t < 300),
            "5_to_30_min": sum(1 for t in response_times if 300 <= t < 1800),
            "30_min_to_2_hours": sum(1 for t in response_times if 1800 <= t < 7200),
            "over_2_hours": sum(1 for t in response_times if t >= 7200)
        }
    }
    
    # Convert seconds to human readable
    analysis["avg_response_time_formatted"] = format_duration(analysis["avg_response_time_seconds"])
    
    return analysis

def format_duration(seconds):
    """Format seconds into human readable duration"""
    if seconds < 60:
        return f"{int(seconds)} seconds"
    elif seconds < 3600:
        return f"{int(seconds // 60)} minutes"
    else:
        hours = int(seconds // 3600)
        minutes = int((seconds % 3600) // 60)
        return f"{hours}h {minutes}m"

Priority Distribution

Track request priority patterns:
function analyzePriorityDistribution(requests) {
    const priorityStats = {
        low: { count: 0, completed: 0, avg_response_time: 0 },
        medium: { count: 0, completed: 0, avg_response_time: 0 },
        high: { count: 0, completed: 0, avg_response_time: 0 },
        critical: { count: 0, completed: 0, avg_response_time: 0 }
    };
    
    requests.forEach(request => {
        const priority = request.priority;
        priorityStats[priority].count++;
        
        if (request.status === 'completed' && request.response_time_seconds) {
            priorityStats[priority].completed++;
            priorityStats[priority].avg_response_time += request.response_time_seconds;
        }
    });
    
    // Calculate averages
    Object.keys(priorityStats).forEach(priority => {
        const stats = priorityStats[priority];
        if (stats.completed > 0) {
            stats.avg_response_time = Math.round(stats.avg_response_time / stats.completed);
        }
        stats.completion_rate = stats.completed / stats.count;
    });
    
    return priorityStats;
}

Export and Reporting

CSV Export

Export request data for analysis:
import csv
from datetime import datetime

def export_requests_to_csv(filename="requests_export.csv"):
    """Export all requests to CSV file"""
    
    # Get all requests
    all_requests = []
    offset = 0
    limit = 100
    
    while True:
        response = requests.get(
            "https://api.hitl.sh/v1/requests",
            headers={"Authorization": "Bearer your_api_key_here"},
            params={"limit": limit, "offset": offset}
        )
        
        data = response.json()["data"]
        all_requests.extend(data["requests"])
        
        if not data["has_more"]:
            break
        offset += limit
    
    # Write to CSV
    with open(filename, 'w', newline='', encoding='utf-8') as csvfile:
        fieldnames = [
            'id', 'loop_id', 'processing_type', 'type', 'priority',
            'request_text', 'response_type', 'status', 'response_data',
            'response_time_seconds', 'created_at', 'response_at'
        ]
        
        writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
        writer.writeheader()
        
        for request in all_requests:
            # Clean data for CSV
            row = {field: request.get(field, '') for field in fieldnames}
            
            # Truncate long text fields
            if len(str(row['request_text'])) > 1000:
                row['request_text'] = str(row['request_text'])[:997] + "..."
            
            writer.writerow(row)
    
    print(f"Exported {len(all_requests)} requests to {filename}")
    return filename

Error Handling

Next Steps

Get Specific Request

Retrieve detailed information about a specific request including response data.

Create New Request

Create a new human review request within a loop.

Request Analytics

Get deeper insights into request patterns and performance metrics.