Marketplace
The marketplace uses the fleet database handtohuman, resolved through Stado and Skarbiec. Every mutating command returns the resulting record as JSON by default; --text prints the same result as path-and-value lines. A declaration is not proof of connectivity: a failed resolve, credential read, TLS connection, or migration stops the command with its cause.
handtohuman market account-create
handtohuman market account-show
handtohuman market payment-intent
handtohuman market payment-settle
handtohuman market offer-create
handtohuman market offer-show
handtohuman market draft-import
handtohuman market draft-show
handtohuman market order-create
handtohuman market order-show
handtohuman market order-fund
handtohuman market order-dispatch
handtohuman market order-start
handtohuman market order-deliver
handtohuman market order-accept
handtohuman market dispute-open
handtohuman market dispute-resolve
handtohuman market rate
handtohuman market payout-request
handtohuman market payout-completeOffer kinds and execution
humanizationugc-videoPerformed by a person on this ledger. Assign the funded order with market order-assign; market order-dispatch refuses these kinds and says so.
computeDispatch the order's command through stado submit, retaining Stado's job id as the execution identity.
residential-egressUses Stado to place handtohuman-egress on the supplier host. Weles must be placed on that same host.
Residential egress binds loopback only, accepts HTTP CONNECT only, requires a lease token injected from Skarbiec, allows only declared domains on ports 80 and 443, rejects private and link-local destinations, and enforces a lease byte cap.
Money lifecycle
External payment and payout providers remain authoritative for money movement. Every credit points at one: payment-intent records what a buyer means to deposit and credits nothing, payment-settle credits it against the provider’s own reference, and that reference is unique across the ledger, so replaying one external payment refuses by name. Payout requests reserve balance atomically and payout-complete takes the transfer’s reference.
- Funding debits the customer into escrow.
- Acceptance records the rate card's
platform_fee_bpsshare and releases the exact remaining minor units to the worker. - A dispute can refund, release, or split the exact escrow total. No path may create or lose cents.
- Ratings are accepted only after settlement and only from an order party.
- Worker reputation is the average of retained order ratings.
- A payout request atomically reserves available worker balance so concurrent requests cannot spend it twice.
Mobile worker app
mobile/ is the iOS and Android worker app. It uses the same marketplace, ledger, escrow, task states, and payouts as the CLI; it is not a second marketplace.
A worker can see assigned work and its brief, start a funded order, record UGC with the phone camera, attach documents, deliver evidence, see currency-separated balances and ratings, and request a payout.
Security and deployment
The app talks only to handtohuman-mobile-api. Each bearer token maps to one worker account in the ledger, so a client cannot select another worker id. Every task read or mutation checks ownership. Upload names are replaced with generated ids (an alphanumeric extension is kept), request bodies are not capped by the product, and files are written beneath the configured upload root, HANDTOHUMAN_MOBILE_UPLOADS.
The API listens only on HANDTOHUMAN_MOBILE_BIND, the address its service declaration assigns, and sends a worker back from payout onboarding to HANDTOHUMAN_MOBILE_ONBOARDING_RETURN_URL, a page the operator names; no host is built in. All three are required: unset or empty, the API exits naming the variable and what it holds, for example HANDTOHUMAN_MOBILE_UPLOADS is not set: set it to the upload directory the service declaration assigns. Expose it to phones only through the authenticated Wisent service ingress with TLS.
# Stado resolves the handtohuman fleet database and its Skarbiec credential.
export HANDTOHUMAN_MOBILE_UPLOADS=/var/lib/handtohuman/uploads
export HANDTOHUMAN_MOBILE_BIND='<the address the service declaration assigns>'
export HANDTOHUMAN_MOBILE_ONBOARDING_RETURN_URL='https://<your-site>/payouts-ready'
handtohuman-mobile-apiA delivery is one multipart form. delivery and evidence carry JSON, file carries any file, and a part named for one of the evidence fields the order's kind requires (for a humanization document and recording, for a UGC video video and consent) carries that artifact and fills the field with the stored path. A part without a name, a name none of these is, and an artifact whose evidence is not a JSON object are refused, so a misspelled part is never delivered as missing.
The unauthenticated GET /healthz endpoint reports process readiness. Mobile operations use authenticated routes:
/v1/signup/v1/mobile/me/v1/mobile/me/connect/v1/mobile/me/payout-destination/v1/mobile/tasks/v1/mobile/tasks/{id}/v1/mobile/tasks/{id}/start/v1/mobile/tasks/{id}/deliver/v1/mobile/payoutsLocal app development
cd mobile
npm install
npm run ios # or: npm run androidThe app requires an HTTPS API URL and stores its bearer token in the platform secure store. Camera, microphone, and document access are requested only when the worker records or selects a delivery.
The five products
One ledger, one lifecycle, five things to sell. Two families, and the difference is who knows the price: labour priced from a published card, and capacity priced by the supplier in their own offer, the way a GPU host sets an hourly rate.
01 / text
humanization
A rewrite written by a person, billed in the rate card's words_per_unit units, rounded up. Delivery carries the document and a continuous recording of the writing session. Our own offering.
02 / media
ugc_video
Original video from a creator, billed per video from the card. Delivery carries the video and the creator's release for the declared usage.
03 / machines
compute
GPU and sandbox hours, billed per GPU hour at the host's listed rate and dispatched through Stado. Delivery carries the job log.
04 / network
residential_egress
Bandwidth from a residential line, billed per gigabyte at the owner's listed rate. Delivery carries the metered byte count.
05 / devices
phone_sharing
A real line for SMS and app verification, billed per device hour at the owner's listed rate. Delivery carries the device and a timestamped session log.
| Kind | Unit | Priced by | Delivery must carry | Market reference |
|---|---|---|---|---|
humanization | words_per_unit words | humanization_unit_cents from the declared card | document, recording | ours |
ugc_video | one video | ugc_video_unit_cents from the declared card | video, consent | SideShift |
compute | GPU hour | supplier's offer | log | vast.ai |
residential_egress | gigabyte | supplier's offer | bytes | Honeygain, IPRoyal Pawns |
phone_sharing | device hour | supplier's offer | device, session_log | sms-activate, Sharing SMS |
Declare the rate card. HANDTOHUMAN_RATE_CARD names the JSON file holding prices, words_per_unit, minimum_total_cents, platform_fee_bps, urgency bands and delivery-verification shares. An unset variable, unreadable file, malformed JSON or invalid field refuses with its cause; the product does not substitute prices from a competitor or a built-in schedule.
Urgency bands are ordered by below_minutes, with the final band omitting that boundary. Their bps multiplier applies after the card-priced minimum. A quote exposes the billed units, unit price, urgency multiplier, platform share, total and worker amount. The platform fee rounds down in currency minor units and the worker receives the exact remainder. An urgency-adjusted total outside the supported minor-unit range is refused rather than wrapped or saturated.
A card quote refuses a capacity kind and says to quote it from an offer; an offer quote takes the kind, the rate, and the currency from the offer itself. A deadline multiplies human work and leaves capacity alone, because a gigabyte is a gigabyte. The bounty-backed vocabulary of the external provider still maps completed/paid to delivered and closed to cancelled.
Staffing and recovery
Staffing is an assignment, not an auction. A funded order is handed to a named supplier with a deadline, and the deadline is the only thing that can take it away from them.
handtohuman market order-assign <order_id> --worker writer-1 --turnaround-minutes 1440
handtohuman market order-lapsed
handtohuman market order-assign <order_id> --worker writer-2 --turnaround-minutes 1440- Reassignment before the deadline is refused, naming the supplier who still holds the order.
order-lapsedlists every in-progress order whose deadline has passed with nothing delivered, oldest first.- Reassignment closes the previous attempt as
expiredinorder_attempts, increments the attempt count, and leaves the escrow untouched: funded, released, and refunded all read the same before and after.
Measured. A worker held an order past a one-minute deadline, the order appeared in order-lapsed, a second worker took it, and the escrow read 345/0/0 both before and after.