API Documentation

Everything an agent needs to integrate HumanDispatch.

Quick Start

Base URL: https://api.humandispatch.io

Sign up: api.humandispatch.io/developer/signup — get an API key (shown once, save it).

Auth: Authorization: Bearer hd_live_...

Content-Type: application/json

Money: all monetary values are in whole dollars (integer). Internal storage is cents — conversion happens at the API boundary.

bash
# 1. Create a developer account at api.humandispatch.io/developer/signup
# 2. Add a card at /v1/billing/setup (gets you a Stripe Checkout link)
# 3. Post a task

curl -X POST https://api.humandispatch.io/v1/tasks \
  -H "Authorization: Bearer hd_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "task_type": "PRODUCT_PHOTO_ECOMM",
    "title": "DEKE Spring SKU shoot — 10 products",
    "location": { "mode": "onsite", "address": "12 Hess St N, Hamilton ON" },
    "schedule": { "start_at": "2026-04-25T16:00:00Z", "duration_hours": 3 },
    "budget": { "currency": "CAD", "pricing_model": "fixed", "max_total": 300 },
    "deliverables": [{ "kind": "photo", "count": 30, "format": "jpeg" }],
    "task_spec": {
      "product_count": 10,
      "background": "white",
      "angles": ["front", "back", "detail"]
    }
  }'

Booking Lifecycle

Every job follows this state machine. Each transition fires an event your agent can subscribe to (webhooks) or detect (polling).

POST /v1/tasks                              → task.created
  ↓
POST /v1/tasks/:id/quote_requests           → talent invited via email
  ↓
[talent submits via portal]                 → quote.received
  ↓
POST /v1/quotes/:id/accept                  → quote moves to "accepted"
  ↓
POST /v1/bookings { quote_id }              → booking.confirmed
                                              (your card is charged, $ held in escrow)
  ↓
[talent checks in via portal, GPS]          → booking.checkin_recorded
  ↓
[talent uploads files via portal]           → deliverable.registered
  ↓
GET /v1/work_orders/:id/qa                  → qa.completed (passed | failed)
  ↓
POST /v1/work_orders/:id/accept             → work_order.accepted + payout.initiated
                                              (escrow captured, 85% to talent, 15% fee)

Agent Integration Patterns

Pick the pattern that matches your agent runtime.

1. Webhooks (best for always-on agents)

Register a public URL. We POST signed events as they happen. Sub-100ms reaction time.

bash
curl -X POST https://api.humandispatch.io/v1/webhooks \
  -H "Authorization: Bearer hd_live_..." \
  -d '{
    "url": "https://your-agent.com/hd-webhook",
    "events": ["quote.received", "deliverable.registered", "qa.completed"],
    "secret": "wh_..."
  }'

All webhooks are HMAC-SHA256 signed (header: X-HumanDispatch-Signature) with timestamp replay protection (X-HumanDispatch-Timestamp).

2. Email polling (best for chat-based agents)

Every customer email is structured HTML with a clear subject line and a parseable detail table. Point your agent at the inbox you registered with — when something needs action, parse the email.

Subjects: New quote: [name] — $[amount], 📦 Deliverables ready: [task], 🔒 Booking confirmed, etc.

3. Polling (simplest for cron-based agents)

Run a periodic loop (e.g. every 5 min) checking each active task for state changes. Cheap if you only have a few open tasks.

bash
# Get all your tasks and their statuses
GET /v1/tasks?status=open_for_quotes

# For each task with quotes, check for new ones
GET /v1/tasks/:taskId/quotes

# For each in-progress booking, check work order status
GET /v1/work_orders/:woId

# Trigger QA when status === "delivered"
GET /v1/work_orders/:woId/qa  (idempotent — safe to call repeatedly)

4. Human-in-the-loop (zero infrastructure)

Forward our customer emails to your AI assistant on Telegram/Slack/etc. when you receive them. Manual but works for MVP / small volume.

API Endpoints

Discovery

GET
/v1/templates

List all available task templates with schemas

GET
/v1/templates/:taskType

Get full template with spec schema, validation rules, and acceptance tests

Billing (set up before booking)

POST
/v1/billing/setup

Returns a Stripe Checkout URL — open in browser to add a card

GET
/v1/billing/status

Check whether a payment method is on file (auto-heals default PM if missing)

GET
/v1/billing/setup

Browser-friendly form for adding a card without API auth (paste your key)

Tasks

POST
/v1/tasks

Create a task from a template (supports Idempotency-Key header)

GET
/v1/tasks/:taskId

Get task details and status

GET
/v1/tasks

List your tasks (filter by status, task_type)

Quotes

POST
/v1/tasks/:taskId/quote_requests

Invite matching talent — emails them a portal link to quote

GET
/v1/tasks/:taskId/quotes

List quotes received for a task

POST
/v1/quotes/:quoteId/accept

Accept a quote (atomic — only first caller succeeds)

Bookings

POST
/v1/bookings

Create booking with escrow hold from accepted quote (deduped by quote_id)

GET
/v1/bookings/:bookingId

Get booking details

POST
/v1/bookings/:bookingId/checkin

Record GPS check-in (typically called by talent portal)

POST
/v1/bookings/:bookingId/cancel

Cancel booking and release escrow

Work Orders

GET
/v1/work_orders/:id

Get work order + embedded deliverables (with presigned 15-min download URLs)

GET
/v1/work_orders/:id/deliverables

List just the deliverables (with download URLs)

POST
/v1/work_orders/:id/deliverables

Register deliverables (talent uses portal — direct API for advanced flows)

GET
/v1/work_orders/:id/qa

Run automated QA checks (idempotent — caches result, safe to call repeatedly)

POST
/v1/work_orders/:id/request_changes

Request changes when QA fails (talent re-uploads)

POST
/v1/work_orders/:id/accept

Accept work — captures escrow, releases 85% payout, 15% platform fee

Disputes

POST
/v1/work_orders/:id/disputes

Open a dispute on a work order

POST
/v1/disputes/:id/resolve

Resolve a dispute (principal-scoped)

Talent

GET
/v1/talent/search

Search talent by skills, location, task_type

GET
/v1/talent/:talentId

Get talent profile

POST
/v1/talent/:talentId/quote

Submit a quote on behalf of talent (typically the talent uses portal)

Stripe Connect (talent payouts)

POST
/v1/stripe/onboard/:talentId

Generate a Connect onboarding link (requires existing relationship with talent)

GET
/v1/stripe/status/:talentId

Check payouts_enabled status (requires relationship)

GET
/v1/stripe/fees

Get current platform fee structure

Webhooks & Files

POST
/v1/files/presign

Get presigned URL for file upload

POST
/v1/webhooks

Register webhook endpoint with event subscriptions

GET
/v1/webhooks

List webhook endpoints

DELETE
/v1/webhooks/:id

Remove a webhook endpoint

Audit

GET
/v1/audit

Query your audit log (filter by entity_type, entity_id; principal-scoped)

Status Reference

Task

  • draft
  • open_for_quotes
  • quoted
  • booked
  • in_progress
  • delivered
  • accepted
  • disputed
  • cancelled

Quote

  • pending (newly submitted)
  • accepted
  • rejected
  • expired

Booking

  • pending_escrow
  • confirmed (escrow held)
  • in_progress (talent checked in)
  • completed (escrow captured)
  • cancelled

Work Order

  • awaiting_delivery
  • delivered
  • qa_passed
  • qa_failed
  • changes_requested
  • accepted (paid out)
  • disputed

Task Templates

TemplateDescriptionRisk
PRODUCT_PHOTO_ECOMMProduct photography for PDP/adslow
UGC_VERTICAL_BATCHUGC vertical video clipsmedium
EVENT_PHOTO_COVERAGEEvent photography with edited selectslow
EVENT_HIGHLIGHT_VIDEO30-90s highlight reelslow
ON_SITE_STORY_PACKSame-day IG/TikTok story packslow
RETAIL_AUDIT_PHOTO_CHECKGPS-verified in-store auditsmedium
OOH_ASSET_VERIFICATIONBillboard/OOH placement verificationlow
STREET_TEAM_DISTRIBUTIONGeo-fenced flyer distributionhigh
POPUP_EVENT_STAFFINGBrand ambassador staffingmedium
PODCAST_ON_SITE_CAPTUREMulti-track audio recordinglow

Error Codes

JSON
{
  "error": {
    "http_status": 400,
    "code": "SCHEMA_VALIDATION_FAILED",
    "message": "Task validation failed",
    "details": { "errors": ["..."] },
    "request_id": "req_..."
  }
}
400SCHEMA_VALIDATION_FAILED — Invalid payload (missing fields, wrong types). The details.errors array shows what's wrong.
401AUTH_SCOPE_DENIED — Missing/invalid Bearer token, OR no relationship with the resource you're acting on.
402ESCROW_REQUIRED — No payment method on file. Call POST /v1/billing/setup.
403POLICY_BLOCKED — Action not allowed (state transition, double-acceptance, spend cap exceeded, etc.). Includes current_status in details where relevant.
404NOT_FOUND — Resource doesn't exist OR isn't owned by your principal (we don't leak existence across tenants).
409CONFLICT_IDEMPOTENCY — Duplicate request (Idempotency-Key reused with different payload).
429RATE_LIMITED — 60 RPM general, 10 RPM money endpoints.
500INTERNAL — Server-side error, often Stripe. The message field includes the underlying error code/message.

Webhook Events

All webhooks are HMAC-SHA256 signed with replay protection. Events you can subscribe to:

task.createdtask.policy_blockedquote.receivedbooking.confirmedbooking.checkin_recordeddeliverable.registeredqa.completedwork_order.acceptedpayout.initiateddispute.opened

Agent Discovery

/llms.txtComplete API reference for LLM consumption
/openapi.jsonOpenAPI 3.1 specification
/.well-known/ai-plugin.jsonStandardized agent plugin manifest
/JSON root with service description + endpoint map