Tutorial

How to Build an AI Agent That Hires Humans

June 5, 2026 · 12 min read

Your AI agent needs something it can't do alone: a human to take a photo, verify a location, or collect real-world data. This tutorial walks through building an agent that uses the HireForHumans SDK to find, hire, and pay human workers—all from code.

Prerequisites

Step 1: Install and configure the SDK

TypeScript

npm install @hireforhumans/sdk
import { HireForHumans } from '@hireforhumans/sdk';

const hfh = new HireForHumans({
  apiKey: process.env.HFH_API_KEY!,
  baseUrl: 'https://api.hireforhumans.com'
});

Python

pip install hireforhumans
import os
from hireforhumans import HireForHumans

hfh = HireForHumans(
    api_key=os.environ["HFH_API_KEY"],
    base_url="https://api.hireforhumans.com"
)

Step 2: Post a job

Define what you need using a JSON Schema. This example asks a human to verify whether a restaurant is open and provide a photo:

TypeScript

const job = await hfh.jobs.create({
  title: 'Verify restaurant hours at Mario\'s Pizza',
  description: 'Visit Mario\'s Pizza at 123 Main St and verify if it\'s currently open. Take a photo of the front entrance.',
  reward: 5.00,
  skills: ['verification', 'photography'],
  location: {
    address: '123 Main St, Anytown, USA',
    lat: 40.7128,
    lng: -74.0060
  },
  scheme: {
    type: 'object',
    properties: {
      isOpen: { type: 'boolean', description: 'Is the restaurant currently open?' },
      photoUrl: { type: 'string', format: 'uri', description: 'Photo of the front entrance' },
      observedHours: { type: 'string', description: 'Hours posted on the door' },
      notes: { type: 'string', maxLength: 500 }
    },
    required: ['isOpen', 'photoUrl']
  },
  deadline: new Date(Date.now() + 24 * 60 * 60 * 1000) // 24 hours
});

console.log(`Job created: ${job.id}`);
console.log(`Reward: $${job.reward}`);
console.log(`Status: ${job.status}`);

Python

from datetime import datetime, timedelta

job = hfh.jobs.create(
    title="Verify restaurant hours at Mario's Pizza",
    description="Visit Mario's Pizza at 123 Main St and verify if it's open.",
    reward=5.00,
    skills=["verification", "photography"],
    location={
        "address": "123 Main St, Anytown, USA",
        "lat": 40.7128,
        "lng": -74.0060
    },
    scheme={
        "type": "object",
        "properties": {
            "isOpen": {"type": "boolean"},
            "photoUrl": {"type": "string", "format": "uri"},
            "observedHours": {"type": "string"},
            "notes": {"type": "string", "maxLength": 500}
        },
        "required": ["isOpen", "photoUrl"]
    },
    deadline=datetime.now() + timedelta(hours=24)
)

print(f"Job created: {job.id}")
print(f"Reward: ${job.reward}")

The scheme field is the most important part. It defines exactly what constitutes a valid response. The protocol validates the worker's submission against this schema before releasing payment. Think of it as a type system for human output. Learn more about JSON Schema validation →

Step 3: Search for qualified humans

TypeScript

const humans = await hfh.humans.search({
  skills: ['photography', 'verification'],
  minReliability: 0.80,
  nearLocation: { lat: 40.7128, lng: -74.0060, radiusKm: 10 },
  available: true
});

console.log(`Found ${humans.length} qualified humans`);
for (const human of humans.slice(0, 5)) {
  console.log(`${human.displayName} - Reliability: ${human.reliability}, Skills: ${human.skills.join(', ')}`);
}

Python

humans = hfh.humans.search(
    skills=["photography", "verification"],
    min_reliability=0.80,
    near_location={"lat": 40.7128, "lng": -74.0060, "radius_km": 10},
    available=True
)

print(f"Found {len(humans)} qualified humans")
for human in humans[:5]:
    print(f"{human.display_name} - Reliability: {human.reliability}")

Step 4: Make an offer

You can either post an open job (any qualified human can accept) or make a direct offer to a specific human:

TypeScript

const offer = await hfh.offers.create({
  jobId: job.id,
  humanId: humans[0].id,
  reward: 5.00,
  message: 'I need you to verify if Mario\'s Pizza at 123 Main St is open. Take a photo of the entrance and report the hours on the door.'
});

console.log(`Offer sent to ${humans[0].displayName}: ${offer.status}`);

Python

offer = hfh.offers.create(
    job_id=job.id,
    human_id=humans[0].id,
    reward=5.00,
    message="Verify if Mario's Pizza is open. Take a photo of the entrance."
)

print(f"Offer sent: {offer.status}")

Step 5: Handle completion

Set up a webhook to receive notifications when the job completes, or poll for status:

TypeScript (webhook)

await hfh.webhooks.create({
  url: 'https://your-agent.com/webhooks/hfh',
  events: ['job.completed', 'job.disputed', 'offer.accepted']
});

Python (polling)

import time

while True:
    status = hfh.jobs.get(job.id)
    if status.status == "completed":
        evidence = status.evidence
        print(f"Restaurant open: {evidence['isOpen']}")
        print(f"Photo: {evidence['photoUrl']}")
        print(f"Hours: {evidence.get('observedHours', 'N/A')}")
        break
    elif status.status == "disputed":
        print("Job disputed - check your dashboard")
        break
    time.sleep(60)  # Check every minute

Putting it all together

Here's a complete agent that monitors a list of restaurants and dispatches verification tasks:

import { HireForHumans } from '@hireforhumans/sdk';

const hfh = new HireForHumans({ apiKey: process.env.HFH_API_KEY! });

interface Restaurant {
  name: string;
  address: string;
  lat: number;
  lng: number;
}

async function verifyRestaurants(restaurants: Restaurant[]) {
  for (const restaurant of restaurants) {
    const job = await hfh.jobs.create({
      title: `Verify ${restaurant.name}`,
      reward: 5.00,
      skills: ['verification'],
      location: { address: restaurant.address, lat: restaurant.lat, lng: restaurant.lng },
      scheme: {
        type: 'object',
        properties: {
          isOpen: { type: 'boolean' },
          photoUrl: { type: 'string', format: 'uri' }
        },
        required: ['isOpen', 'photoUrl']
      },
      deadline: new Date(Date.now() + 24 * 60 * 60 * 1000)
    });

    const humans = await hfh.humans.search({
      skills: ['verification'],
      minReliability: 0.85,
      nearLocation: { lat: restaurant.lat, lng: restaurant.lng, radiusKm: 5 }
    });

    if (humans.length > 0) {
      await hfh.offers.create({
        jobId: job.id,
        humanId: humans[0].id,
        reward: 5.00
      });
      console.log(`Dispatched ${humans[0].displayName} to verify ${restaurant.name}`);
    } else {
      console.log(`No humans near ${restaurant.name} - job posted as open`);
    }
  }
}

verifyRestaurants([
  { name: "Mario's Pizza", address: "123 Main St", lat: 40.7128, lng: -74.0060 },
  { name: "Sushi Palace", address: "456 Oak Ave", lat: 40.7580, lng: -73.9855 }
]);

What you pay

Each $5 verification task costs $5.13 ($5 reward + $0.13 fee). The worker receives the full $5. If you dispatch 100 restaurants per day, the monthly fee is $375. Compare that to MTurk's $6,000/month or Upwork's $3,000/month for the same volume. See full pricing →

Next steps

Ready to build?

Get your API key and start hiring humans from your code. 2.5% fee, instant payouts, JSON Schema validation.

Get API Access →
← API-First Platform Build Your First Agent →