Human API
Open physical task spec, v1
What you send, what comes back, and how to check the receipt.
This spec describes the on-site tasks you can book through the TeamShift human API: what you send, what proof comes back, how risky each task is, and the receipt you get when it's verified. It's plain JSON Schema, so an agent can check a task before booking it and check the result after. Anyone may use it for their own tasks.
Task types
| Task type | What it is | Risk tier | Photos |
|---|---|---|---|
| photo | Exterior photo or drive-by check, up to 15 minutes on site | exterior | 2 |
| site_check | Site check with a checklist, up to 30 minutes, inside with access you arrange | interior (exterior or entry allowed) | 3 |
| inspection | Inspection with a written report, up to 60 minutes | exterior (interior or entry allowed) | 6 |
| errand | An errand billed by the hour, purchases passed through at cost | exterior | 1 |
Each task type links to its JSON Schema. Photos is the default number of photos asked for.
Shared parts (location, window, proof, risk tier) live in common.schema.json. The list is closed on purpose: a new kind of task arrives as a new schema.
A task
Every task has the same five parts:
task_typeandspec_version("1").risk_tier: how far the person goes.inputs: what the person needs to do the job. Every task has alocationwith a street address and ZIP, and can add awindowand shortinstructions.proof: what counts as proof.output: the structured answer that comes back, so an agent doesn't have to read a paragraph.
A site check that asks whether a gate is shut looks like this:
{
"task_type": "site_check",
"spec_version": "1",
"risk_tier": "exterior",
"inputs": {
"location": {
"address": "120 Main St, Lancaster, PA 17602",
"zip": "17602",
"site": {"lat": 40.0379, "lng": -76.3055, "radius_m": 250}
},
"checklist": [
{"id": "gate_closed", "question": "Is the back gate closed and latched?", "answer": "boolean"}
]
},
"proof": {"shots": 2, "shot_list": ["Back gate", "Latch close-up"], "channel": "capture_link"},
"output": {"answers": {"gate_closed": true}, "note": "Latched, padlock on."}
}
Proof
- Shots. The number of distinct photos needed, 1 to 10. A photo already used on another task never counts.
- Geofence. When the task names a site, each photo's position is compared with it. A photo farther than the radius (250 m by default) is flagged.
- Capture window. Photos taken before the task went out are flagged.
- Channel.
capture_linkis the default: a signed page that records the time and the phone's browser location as each photo is taken.mmsis a photo reply by text. Text messages usually lose the time and place stored in the photo, so the capture link gives stronger proof.
Each verified task also gets a proof confidence score from 0 to 100, with the reasons that make it up: whether the proof came from the person's own reply, whether the photos were taken on site and after dispatch, the person's own look at the photos, and whether enough photos arrived. It's a signal for you to set your own bar, such as "accept at 80 or above". It never changes verification or pay.
Risk tiers
- exterior: photos from public ground or the yard. No extra vetting.
- interior: inside a building, with access you arrange.
- entry: the person gets a key, code or lockbox.
Interior and entry tasks go only to people with a background check that passed in the last 365 days and at least $1,000,000 of liability insurance that hasn't expired. Leave door codes and lockbox numbers out of the task text.
Receipts
Every verified task gets a receipt: a W3C Verifiable Credential 2.0 of type TaskReceipt, issued by did:web:teamshift.io. Its shape is receipt.schema.json. It holds:
- the task ID and type
- the ZIP code only, never the street address or GPS position
- a pseudonymous worker ID, never a name or contact details
- the SHA-256 fingerprint of each proof photo, when it was received, the capture time the photo carried, and whether it was taken inside the task's radius
- the proof confidence score
- the outcome
- the price split into lines, with the platform fee always its own line
Receipts keep this lasting version from the start, so nothing in them has to be removed after the 12 months that photos and precise locations are kept.
Checking a receipt
A signed receipt carries a Data Integrity proof with the eddsa-jcs-2022 cryptosuite. To check it:
- Fetch the public key from /.well-known/did.json. It's the
publicKeyMultibaseofdid:web:teamshift.io#receipt-key-1, an Ed25519 key in Multikey form. - Take the
proofoff the receipt and remove itsproofValue. What's left of the proof is the proof configuration. Its@contextmust equal the receipt's. - Canonicalize the proof configuration and the receipt without its proof with the JSON Canonicalization Scheme (RFC 8785), and hash each with SHA-256.
- Join the two hashes, proof configuration first, and check the Ed25519 signature in
proofValue(base58btc, after the leadingz) against them.
Any change to the receipt, even one character, makes the check fail. A receipt with no proof was issued unsigned and can't be checked this way.
Versioning
This is version 1. A change that could break a reader gets a new version under a new path (/human-api/task-spec/v2/). Version 1 files stay where they are.
Related
- Legal, including the requester terms that cover quotes, refunds, disputes and receipts
- Worker privacy, which sets what a receipt shows about the person who did the task