# Hitworkers API

Hitworkers connects you with real people (workers in 36+ countries) who complete simple online micro-tasks: posts, shares, sign-ups, reviews, tests, data checks. With this API you create campaigns, follow them, and approve or reject each worker's proof, from your own code or from an AI agent such as Claude Code.

## How it works

1. **Create a client account** at https://hitworkers.com/client and **top up your balance by card** (Stripe, USD, minimum $20).
2. **Create an API key** in your client space. It is shown once: store it safely.
3. **Create a campaign** with `POST /campaigns`. Its full budget is reserved on your balance.
4. **Our team reviews every campaign** before it goes live, within a few hours. We may adjust the price, the number of spots or the wording, and we tell you why in `admin_note`. If the campaign is rejected, the full budget returns to your balance.
5. **Workers do the task** and send a proof (text and/or screenshot).
6. **You approve or reject each proof** with the API. Approved tasks are paid to the worker. Please review within 24 hours: workers are promised a fast review.
7. **Cancel or finish**: when a campaign closes, the budget of unused spots returns to your balance.

## Pricing

- You choose `reward_usd`: what one worker earns for one task (minimum $0.15).
- Cost per task = `reward_usd` + 25% platform fee. Budget = cost per task × `slots`.
- The budget is reserved when you create the campaign. Spots that are never used come back to your balance.

Private parts: wrap a link or a code in `||double pipes||` in `instructions`. It is shown only to the worker who takes a spot.

All campaigns go to all workers for now (country targeting is not available yet).

## Authentication

Send your key in the `Authorization` header of every request:

```
Authorization: Bearer hw_live_xxxxxxxxxxxxxxxx
```

Base URL: `https://hitworkers.com/api/v1`. Requests and responses are JSON. Rate limit: 120 requests per minute.

Errors look like `{ "error": { "message": "..." } }` with an HTTP status: 400 invalid input, 401 bad key, 402 insufficient balance, 404 not found, 409 wrong state, 429 too many requests.

## Endpoints

### GET /account

Your balance and pricing rules.

```bash
curl https://hitworkers.com/api/v1/account -H "Authorization: Bearer $HITWORKERS_KEY"
```

```json
{ "email": "you@company.com", "name": "Company", "balance_usd": 120.5,
  "pricing": { "platform_fee_pct": 25, "min_reward_usd": 0.15, "max_instruction_words": 500 },
  "top_up_url": "https://hitworkers.com/client" }
```

### POST /campaigns

Create a campaign. It starts with status `pending_review`.

| Field | Type | Required | Description |
|---|---|---|---|
| title | string | yes | Short task name shown to workers (max 140 characters) |
| instructions | string | yes | Step-by-step instructions, Markdown allowed, **max 500 words** |
| reward_usd | number | yes | What one worker earns for one task (min 0.15, max 100) |
| slots | integer | yes | Number of workers / tasks (30 to 10000) |
| proof_hint | string | no | What the worker must paste as proof (e.g. "Link to your post") |
| proof_type | string | no | `screenshot` (default), `text` or `file` (photo, audio, PDF) |
| review_hours | integer | no | Time you have to review each proof before it is approved automatically: 24, 48 (default), 72 or 168 |
| is_public | boolean | no | `true` (default) = listed to other clients with private parts masked |
| target_url | string | no | Link the worker must open (http/https) |
| est_minutes | integer | no | Estimated time shown to workers |
| time_limit_minutes | integer | no | Time a worker has to send the proof after taking a spot (5 to 1440, default 60) |

```bash
curl -X POST https://hitworkers.com/api/v1/campaigns \
  -H "Authorization: Bearer $HITWORKERS_KEY" -H "Content-Type: application/json" \
  -d '{
    "title": "Follow our Instagram page and like the last post",
    "instructions": "1. Open the link.\n2. Follow the page.\n3. Like the most recent post.\n4. Take a screenshot showing you follow the page.",
    "reward_usd": 0.15,
    "slots": 100,
    "proof_hint": "Your Instagram username",
    "proof_type": "screenshot",
    "target_url": "https://instagram.com/yourpage",
    "est_minutes": 3
  }'
```

Response `201`: the campaign object (see below). Response `402`: balance too low, top up first.

### GET /campaigns

List your campaigns (most recent first).

### GET /campaigns/{id}

One campaign. The campaign object:

```json
{ "id": "uuid", "status": "pending_review | live | paused | closed | rejected",
  "title": "...", "instructions": "...", "reward_usd": 0.15, "cost_per_task_usd": 0.1875,
  "slots": 100, "countries": [], "target_url": null, "proof_hint": "...", "proof_type": "screenshot", "review_hours": 48,
  "budget_held_usd": 18.75,
  "submissions": { "in_progress": 3, "to_review": 12, "approved": 40, "rejected": 2 },
  "admin_note": null, "created_at": "2026-10-25T10:00:00.000Z", "published_at": "2026-10-25T12:00:00.000Z" }
```

### POST /campaigns/{id}/cancel

Close the campaign. Budget of unused spots returns to your balance (`refunded_usd` in the response). Proofs already sent can still be reviewed.

### GET /campaigns/{id}/submissions?status=to_review

Worker proofs. `status` filter: `in_progress`, `to_review`, `approved`, `rejected`, `expired` (default: all except expired).

```json
{ "data": [ { "id": "uuid", "status": "to_review", "worker": "worker_ab12", "country": "IN",
  "proof_text": "my_username", "proof_image_url": "https://hitworkers.com/api/v1/submissions/uuid/image",
  "submitted_at": "2026-10-25T12:30:00.000Z", "reviewed_at": null, "review_note": null } ] }
```

### GET /submissions/{id}/image

The screenshot (image bytes). Send your API key as for any request.

### POST /submissions/{id}/approve

Approve a proof (status must be `to_review`). The worker gets paid.

### POST /submissions/{id}/reject

Reject a proof. Body: `{ "reason": "Screenshot does not show the follow" }`. The reason is shown to the worker. The spot opens again for another worker.

## MCP (Claude Code and other AI agents)

Hitworkers is also an MCP server, so an agent can use it as a set of tools. Endpoint: `https://hitworkers.com/api/mcp` (Streamable HTTP), same API key.

Claude Code:

```bash
claude mcp add --transport http hitworkers https://hitworkers.com/api/mcp --header "Authorization: Bearer hw_live_xxxxxxxxxxxxxxxx"
```

Then ask in plain words, for example: "Launch a task: 100 people in India, Pakistan and the Philippines test our signup page, $0.50 each, screenshot as proof."

Tools: `get_account`, `create_campaign`, `list_campaigns`, `get_campaign`, `cancel_campaign`, `list_submissions`, `approve_submission`, `reject_submission`. They follow the same rules as the REST API (review by our team, budget reserved, 500 words max).

## Typical loop for an AI agent

1. `GET /account` → check `balance_usd` covers `slots × reward_usd × 1.25`.
2. `POST /campaigns` with clear, numbered instructions (max 500 words) and a precise `proof_hint`.
3. Poll `GET /campaigns/{id}` until `status` is `live` (or `rejected`: read `admin_note`).
4. Every few hours: `GET /campaigns/{id}/submissions?status=to_review`, check each proof against the instructions (download `proof_image_url` with the key), then `approve` or `reject` with a clear reason.
5. When you have enough results: `POST /campaigns/{id}/cancel` to get unused budget back.

## Good instructions

- Number the steps. One action per step.
- Say exactly what the proof must show.
- Say what gets rejected (copied text, deleted post, wrong account…).
- No illegal, adult, gambling, misleading or account-selling tasks: they are rejected at review.

Machine-readable spec: https://hitworkers.com/openapi.json · This page as Markdown: https://hitworkers.com/docs.md
