{"openapi":"3.1.0","info":{"title":"WayHand API","version":"1.0.0","description":"Cross-border errands paid through OPUS escrow (USDC on Polygon).\n\n**Public** endpoints need no sign-in and never show applicant notes or proof.\n**Private** endpoints need `Authorization: Bearer <token>` from wallet sign-in (`/auth/nonce`, then `/auth/verify`).\nEverything the web app's screens do is one of these operations.\n\nFlow: `createErrand` (client) → `applyToErrand` (provider) → `chooseApplicant` and `fundErrand` (client) →\n`submitProof` (provider) → `confirmErrand` (client), or payment goes out on its own when the time to check ends.\nThe client sets the time to check (`reviewHours`) and a one-time extension limit (`maxExtensionHours`) when posting;\nwhile checking, `extendReview` adds time once.\nEach private errand lists the `actions` the caller may take next; each action is `POST /private/errands/{id}/<action>`.\n\nErrors are `{ error: { code, message, vars } }`. `code` is stable; `message` follows `?lang=` or `Accept-Language`.\nWhile `meta.trial` is true no money moves: `fundErrand` and `confirmErrand` only record the step."},"servers":[{"url":"/api/v1"}],"tags":[{"name":"public","description":"No sign-in. Read-only."},{"name":"auth","description":"Wallet sign-in (EIP-4361) that returns a bearer token."},{"name":"private","description":"Bearer token required. Every action a screen offers."}],"paths":{"/public/meta":{"get":{"operationId":"getMeta","summary":"Limits, categories, countries, escrow contracts, trial flag","tags":["public"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Meta"}}}}}}}}},"/health":{"get":{"operationId":"getHealth","summary":"Is the service working? (for uptime monitors)","description":"200 when the database reads and, with the real escrow, the network sync is working and the contracts match. 503 with `problems` otherwise.","tags":["public"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"object","properties":{"status":{"type":"string","enum":["ok","degraded","down"]}}}}}}}},"503":{"description":"Degraded or down; see `data.problems`"}}}},"/public/rates":{"get":{"operationId":"getRates","summary":"Approximate yen and won per US dollar (display only)","description":"Shown as small local amounts beside USDC for Japanese and Korean readers. `source` is `live` or `fallback` (saved numbers). Nothing is charged by these numbers.","tags":["public"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Rates"}}}}}}}}},"/public/errands":{"get":{"operationId":"listErrands","summary":"List errands (default: open ones)","tags":["public"],"parameters":[{"name":"status","in":"query","schema":{"$ref":"#/components/schemas/Status"}},{"name":"category","in":"query","schema":{"$ref":"#/components/schemas/Category"}},{"name":"country","in":"query","schema":{"$ref":"#/components/schemas/Country"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1}},{"name":"pageSize","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":50,"default":12}},{"name":"lang","in":"query","required":false,"description":"Language of messages and sample texts. `Accept-Language` works too.","schema":{"type":"string","enum":["en","ko","ja","zh"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"object","description":"One page of a list. A page past the end returns the last page.","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/PublicErrand"}},"total":{"type":"integer","description":"Everything that matches, over all pages"},"page":{"type":"integer"},"pageSize":{"type":"integer"},"pages":{"type":"integer","description":"Number of pages, at least 1"}}}}}}}}}}},"/public/errands/{id}":{"get":{"operationId":"getErrand","summary":"One errand, public view","tags":["public"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"lang","in":"query","required":false,"description":"Language of messages and sample texts. `Accept-Language` works too.","schema":{"type":"string","enum":["en","ko","ja","zh"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/PublicErrand"}}}}}},"404":{"description":"No such errand","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/public/providers/{address}":{"get":{"operationId":"getProvider","summary":"A provider's profile and record","description":"Public. The profile the wallet filled in (areas, categories, languages, or null) and its record counted from the errands: completed, on time, cancelled by agreement (never a penalty) and in progress. `suspended` is true for a wallet kept from applying.","tags":["public"],"parameters":[{"name":"address","in":"path","required":true,"schema":{"type":"string","pattern":"^0x[0-9a-fA-F]{40}$","description":"Wallet address"}},{"name":"lang","in":"query","required":false,"description":"Language of messages and sample texts. `Accept-Language` works too.","schema":{"type":"string","enum":["en","ko","ja","zh"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Provider"}}}}}},"404":{"description":"No such errand","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/auth/nonce":{"post":{"operationId":"getSignInNonce","summary":"Step 1 of sign-in: get a nonce and the SIWE message fields","description":"Build an EIP-4361 message with these fields and your address (version 1, issuedAt now), then sign it with personal_sign.","tags":["auth"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["address"],"properties":{"address":{"type":"string","pattern":"^0x[0-9a-fA-F]{40}$","description":"Wallet address"}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Nonce"}}}}}},"400":{"description":"The request breaks a rule","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/auth/verify":{"post":{"operationId":"signIn","summary":"Step 2 of sign-in: send the signed message, get a bearer token","tags":["auth"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["message","signature"],"properties":{"message":{"type":"string"},"signature":{"type":"string"}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Session"}}}}}},"401":{"description":"Sign-in missing or expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/private/me":{"get":{"operationId":"getMe","summary":"The signed-in wallet and its counts","tags":["private"],"security":[{"wallet":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Me"}}}}}},"401":{"description":"Sign-in missing or expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/private/errands":{"get":{"operationId":"listMyErrands","summary":"Errands I posted","tags":["private"],"security":[{"wallet":[]}],"parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1}},{"name":"pageSize","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":50,"default":12}},{"name":"lang","in":"query","required":false,"description":"Language of messages and sample texts. `Accept-Language` works too.","schema":{"type":"string","enum":["en","ko","ja","zh"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"object","description":"One page of a list. A page past the end returns the last page.","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/PrivateErrand"}},"total":{"type":"integer","description":"Everything that matches, over all pages"},"page":{"type":"integer"},"pageSize":{"type":"integer"},"pages":{"type":"integer","description":"Number of pages, at least 1"}}}}}}}},"401":{"description":"Sign-in missing or expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"createErrand","summary":"Post an errand","description":"Send an `Idempotency-Key` header so a retried request does not post twice. Only `meta.openCategories` and `meta.openCountries` can be posted; buying (`buy`) returns `error.categoryClosed` until arbiters exist (an administrator wallet or an invited wallet may post `meta.previewCategories` on a test network, never on the main network), other countries `error.countryClosed`. Start from `meta.templates` when one fits.","tags":["private"],"security":[{"wallet":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string"}},{"name":"lang","in":"query","required":false,"description":"Language of messages and sample texts. `Accept-Language` works too.","schema":{"type":"string","enum":["en","ko","ja","zh"]}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateErrand"}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/PrivateErrand"}}}}}},"400":{"description":"The request breaks a rule","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Sign-in missing or expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed for your role","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such errand","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Not allowed in the current status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/private/jobs":{"get":{"operationId":"listMyJobs","summary":"Errands I am doing, and open errands I applied to","tags":["private"],"security":[{"wallet":[]}],"parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1}},{"name":"pageSize","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":50,"default":12}},{"name":"lang","in":"query","required":false,"description":"Language of messages and sample texts. `Accept-Language` works too.","schema":{"type":"string","enum":["en","ko","ja","zh"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"object","description":"One page of a list. A page past the end returns the last page.","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/PrivateErrand"}},"total":{"type":"integer","description":"Everything that matches, over all pages"},"page":{"type":"integer"},"pageSize":{"type":"integer"},"pages":{"type":"integer","description":"Number of pages, at least 1"}}}}}}}},"401":{"description":"Sign-in missing or expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/private/errands/{id}":{"get":{"operationId":"getMyErrand","summary":"One errand as I see it","description":"Includes `role`, `actions`, and proof if allowed.","tags":["private"],"security":[{"wallet":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"lang","in":"query","required":false,"description":"Language of messages and sample texts. `Accept-Language` works too.","schema":{"type":"string","enum":["en","ko","ja","zh"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/PrivateErrand"}}}}}},"400":{"description":"The request breaks a rule","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Sign-in missing or expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed for your role","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such errand","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Not allowed in the current status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/private/errands/{id}/apply":{"post":{"operationId":"applyToErrand","summary":"Apply to an open errand","description":"Anyone but the client.","tags":["private"],"security":[{"wallet":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"lang","in":"query","required":false,"description":"Language of messages and sample texts. `Accept-Language` works too.","schema":{"type":"string","enum":["en","ko","ja","zh"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/PrivateErrand"}}}}}},"400":{"description":"The request breaks a rule","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Sign-in missing or expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed for your role","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such errand","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Not allowed in the current status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"city":{"type":"string","maxLength":60},"message":{"type":"string","maxLength":500}}}}}}}},"/private/errands/{id}/choose":{"post":{"operationId":"chooseApplicant","summary":"Choose an applicant","description":"Client only, while the errand is open.","tags":["private"],"security":[{"wallet":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"lang","in":"query","required":false,"description":"Language of messages and sample texts. `Accept-Language` works too.","schema":{"type":"string","enum":["en","ko","ja","zh"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/PrivateErrand"}}}}}},"400":{"description":"The request breaks a rule","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Sign-in missing or expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed for your role","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such errand","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Not allowed in the current status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["applicant"],"properties":{"applicant":{"type":"string","pattern":"^0x[0-9a-fA-F]{40}$","description":"Wallet address"}}}}}}}},"/private/errands/{id}/fund":{"post":{"operationId":"fundErrand","summary":"Put the payment in escrow","description":"Client only, after choosing. In trial the call only records the step. With the real escrow (`meta.chain.mode` is `chain`) the client first creates, prices, configures and funds the job from their wallet, then sends its `jobId`; the server reads the job from the network and funds the errand only if it matches the errand's terms (client, provider, amount, evaluator and hook, agreement hash, time to check, extension, mode and submit window). One job can fund one errand.","tags":["private"],"security":[{"wallet":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"lang","in":"query","required":false,"description":"Language of messages and sample texts. `Accept-Language` works too.","schema":{"type":"string","enum":["en","ko","ja","zh"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/PrivateErrand"}}}}}},"400":{"description":"The request breaks a rule","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Sign-in missing or expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed for your role","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such errand","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Not allowed in the current status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"jobId":{"type":"string","description":"Escrow job id, decimal text"},"txHash":{"type":"string"}}}}}}}},"/private/errands/{id}/relay":{"post":{"operationId":"relayErrandCall","summary":"Send a signed escrow call so the network fee is paid for you","description":"With the real escrow only. The caller signs an escrow call in their wallet (the SDK's `signForwardRequest`) instead of sending it, so no POL is needed. The client or the chosen provider may send it. Only some functions are forwarded (create, price, configure and fund the job; submit; approve or extend the review; refund; withdraw to yourself), only for this errand's own job and only at the step where the call can work. A refusal names the reason (`sender`, `role`, `target`, `function`, `job`, `step`, `amount`, `recipient`). If the service is down, or its budget or a limit is spent, the error is `error.relayUnavailable`: send the call from your own wallet instead. Other answers: `error.relayReverted` (the network did not accept the step; reload and retry), `error.relayExpired` (sign again), `error.relaySanctioned`.","tags":["private"],"security":[{"wallet":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"lang","in":"query","required":false,"description":"Language of messages and sample texts. `Accept-Language` works too.","schema":{"type":"string","enum":["en","ko","ja","zh"]}}],"responses":{"200":{"description":"Sent","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"hash":{"type":"string"},"pending":{"type":"boolean"}}}}}}}},"400":{"description":"The request breaks a rule","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Sign-in missing or expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed for your role","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such errand","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Not allowed in the current status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["from","to","value","gas","deadline","data","signature"],"properties":{"from":{"type":"string","description":"The signing wallet; must be the caller"},"to":{"type":"string","description":"The escrow instance or evaluator"},"value":{"type":"string","description":"Always `0`"},"gas":{"type":"string","description":"Gas limit, decimal text, at most 1500000"},"deadline":{"type":"integer","description":"Unix seconds, at most one hour ahead"},"data":{"type":"string","description":"The call data, hex"},"signature":{"type":"string","description":"The EIP-712 signature, hex"}}}}}}}},"/private/errands/{id}/submit":{"post":{"operationId":"submitProof","summary":"Submit proof of completion","description":"Chosen provider only, after funding. Photos are JPEG, PNG or WebP data URLs, up to 6.","tags":["private"],"security":[{"wallet":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"lang","in":"query","required":false,"description":"Language of messages and sample texts. `Accept-Language` works too.","schema":{"type":"string","enum":["en","ko","ja","zh"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/PrivateErrand"}}}}}},"400":{"description":"The request breaks a rule","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Sign-in missing or expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed for your role","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such errand","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Not allowed in the current status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["photos"],"properties":{"photos":{"type":"array","maxItems":6,"items":{"type":"string"}},"tracking":{"type":"string","maxLength":80},"memo":{"type":"string","maxLength":1000},"txHash":{"type":"string","description":"With the real escrow: the provider's `submit` transaction. Its deliverable must equal the hash of this proof (see `deliverableDigest`). With a proof given beforehand (`stageProof`), send only this, without photos"}}}}}}}},"/private/errands/{id}/proof":{"post":{"operationId":"stageProof","summary":"Give the proof first (real escrow)","description":"Chosen provider only, while the job is still funded. The server keeps the proof and answers with `stagedDigest`: put that as the `deliverable` of `submit` on the escrow. When the escrow shows it, the server takes the proof in by itself, so nothing is lost if you cannot reach it afterwards (or call `submitProof` with `txHash` and no photos). Sending again replaces the held proof until the escrow shows the job as submitted. Photos are JPEG, PNG or WebP data URLs, up to 6.","tags":["private"],"security":[{"wallet":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"lang","in":"query","required":false,"description":"Language of messages and sample texts. `Accept-Language` works too.","schema":{"type":"string","enum":["en","ko","ja","zh"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/PrivateErrand"}}}}}},"400":{"description":"The request breaks a rule","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Sign-in missing or expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed for your role","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such errand","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Not allowed in the current status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["photos"],"properties":{"photos":{"type":"array","maxItems":6,"items":{"type":"string"}},"tracking":{"type":"string","maxLength":80},"memo":{"type":"string","maxLength":1000}}}}}}}},"/private/errands/{id}/video":{"post":{"operationId":"commitVideo","summary":"Send the fingerprint of the proof video","description":"Chosen provider only, while funded, for errands whose `proofs` include `video`. The file stays with the provider.","tags":["private"],"security":[{"wallet":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"lang","in":"query","required":false,"description":"Language of messages and sample texts. `Accept-Language` works too.","schema":{"type":"string","enum":["en","ko","ja","zh"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/PrivateErrand"}}}}}},"400":{"description":"The request breaks a rule","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Sign-in missing or expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed for your role","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such errand","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Not allowed in the current status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["sha256","bytes","mime","code"],"properties":{"sha256":{"type":"string","pattern":"^[0-9a-fA-F]{64}$"},"bytes":{"type":"integer","minimum":1},"mime":{"type":"string","enum":["video/mp4","video/quicktime","video/webm"]},"seconds":{"type":"number","minimum":0},"code":{"type":"string","pattern":"^[0-9]{4}$"}}}}}}},"put":{"operationId":"uploadVideo","summary":"Upload the proof video","description":"Chosen provider only, while funded, for errands whose `proofs` include `video`. The body is the video file itself.","tags":["private"],"security":[{"wallet":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"lang","in":"query","required":false,"description":"Language of messages and sample texts. `Accept-Language` works too.","schema":{"type":"string","enum":["en","ko","ja","zh"]}},{"name":"X-Video-Code","in":"header","required":true,"description":"The code shown in the video: `videoCode` of the errand (today's or yesterday's)","schema":{"type":"string","pattern":"^[0-9]{4}$"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/PrivateErrand"}}}}}},"400":{"description":"The request breaks a rule","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Sign-in missing or expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed for your role","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such errand","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Not allowed in the current status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"video/mp4":{"schema":{"type":"string","format":"binary"}},"video/quicktime":{"schema":{"type":"string","format":"binary"}},"video/webm":{"schema":{"type":"string","format":"binary"}}}}},"get":{"operationId":"getVideo","summary":"Watch the proof video","description":"Client, chosen provider or admin. Supports `Range`. Fetch with the bearer token and play the blob.","tags":["private"],"security":[{"wallet":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"lang","in":"query","required":false,"description":"Language of messages and sample texts. `Accept-Language` works too.","schema":{"type":"string","enum":["en","ko","ja","zh"]}}],"responses":{"200":{"description":"The whole video","content":{"video/mp4":{"schema":{"type":"string","format":"binary"}},"video/quicktime":{"schema":{"type":"string","format":"binary"}},"video/webm":{"schema":{"type":"string","format":"binary"}}}},"206":{"description":"The part asked for with `Range`"},"400":{"description":"The request breaks a rule","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Sign-in missing or expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed for your role","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such errand","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Not allowed in the current status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"416":{"description":"The range cannot be met"}}}},"/private/errands/{id}/object":{"post":{"operationId":"objectToSubmission","summary":"Object to the submission","description":"Client only, while checking a submission on an errand type that allows it (`meta.dispute.categories`). Stops the payment and starts the time to send evidence.","tags":["private"],"security":[{"wallet":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"lang","in":"query","required":false,"description":"Language of messages and sample texts. `Accept-Language` works too.","schema":{"type":"string","enum":["en","ko","ja","zh"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/PrivateErrand"}}}}}},"400":{"description":"The request breaks a rule","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Sign-in missing or expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed for your role","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such errand","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Not allowed in the current status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["reason"],"properties":{"reason":{"type":"string","enum":["notArrived","notMatching","damaged","other"]},"note":{"type":"string","maxLength":1000},"fraud":{"type":"boolean","description":"True when the side that lost cheated: their wallet is kept from using WayHand until an admin lifts it"}}}}}}}},"/private/errands/{id}/dispute/video":{"put":{"operationId":"uploadDisputeVideo","summary":"Upload the unboxing video","description":"Client only, while an objection waits for evidence. The body is the video file itself.","tags":["private"],"security":[{"wallet":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"lang","in":"query","required":false,"description":"Language of messages and sample texts. `Accept-Language` works too.","schema":{"type":"string","enum":["en","ko","ja","zh"]}},{"name":"X-Video-Code","in":"header","required":true,"description":"The code shown in the video: `disputeVideoCode` of the errand (today's or yesterday's)","schema":{"type":"string","pattern":"^[0-9]{4}$"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/PrivateErrand"}}}}}},"400":{"description":"The request breaks a rule","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Sign-in missing or expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed for your role","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such errand","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Not allowed in the current status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"video/mp4":{"schema":{"type":"string","format":"binary"}},"video/quicktime":{"schema":{"type":"string","format":"binary"}},"video/webm":{"schema":{"type":"string","format":"binary"}}}}},"get":{"operationId":"getDisputeVideo","summary":"Watch the unboxing video","description":"Client, chosen provider or admin. Supports `Range`. Fetch with the bearer token and play the blob.","tags":["private"],"security":[{"wallet":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"lang","in":"query","required":false,"description":"Language of messages and sample texts. `Accept-Language` works too.","schema":{"type":"string","enum":["en","ko","ja","zh"]}}],"responses":{"200":{"description":"The whole video","content":{"video/mp4":{"schema":{"type":"string","format":"binary"}},"video/quicktime":{"schema":{"type":"string","format":"binary"}},"video/webm":{"schema":{"type":"string","format":"binary"}}}},"206":{"description":"The part asked for with `Range`"},"400":{"description":"The request breaks a rule","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Sign-in missing or expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed for your role","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such errand","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Not allowed in the current status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"416":{"description":"The range cannot be met"}}}},"/private/errands/{id}/dispute/deposit":{"post":{"operationId":"payDisputeDeposit","summary":"Put down the provider's fee","description":"Chosen provider only, after the client's objection. Both sides put down the same fee (`dispute.depositUsd`): the client when they object, the provider with this call, before `dispute.evidenceDueAt`. Whoever cannot pay or send what they owe in time loses; without the provider's fee the client wins. While the escrow cannot hold fees yet, this is only recorded.","tags":["private"],"security":[{"wallet":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"lang","in":"query","required":false,"description":"Language of messages and sample texts. `Accept-Language` works too.","schema":{"type":"string","enum":["en","ko","ja","zh"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/PrivateErrand"}}}}}},"400":{"description":"The request breaks a rule","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Sign-in missing or expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed for your role","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such errand","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Not allowed in the current status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/private/errands/{id}/dispute/evidence":{"post":{"operationId":"submitDisputeEvidence","summary":"Send the evidence","description":"Client only. Says the evidence is complete; the case goes to the admin.","tags":["private"],"security":[{"wallet":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"lang","in":"query","required":false,"description":"Language of messages and sample texts. `Accept-Language` works too.","schema":{"type":"string","enum":["en","ko","ja","zh"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/PrivateErrand"}}}}}},"400":{"description":"The request breaks a rule","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Sign-in missing or expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed for your role","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such errand","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Not allowed in the current status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/private/errands/{id}/confirm":{"post":{"operationId":"confirmErrand","summary":"Confirm and release payment","description":"Client only, after proof is submitted.","tags":["private"],"security":[{"wallet":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"lang","in":"query","required":false,"description":"Language of messages and sample texts. `Accept-Language` works too.","schema":{"type":"string","enum":["en","ko","ja","zh"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/PrivateErrand"}}}}}},"400":{"description":"The request breaks a rule","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Sign-in missing or expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed for your role","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such errand","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Not allowed in the current status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/private/errands/{id}/extend":{"post":{"operationId":"extendReview","summary":"Add time to check, once","description":"Client only, while checking a submission and before the time to check ends. `hours` is at most the errand's `maxExtensionHours`.","tags":["private"],"security":[{"wallet":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"lang","in":"query","required":false,"description":"Language of messages and sample texts. `Accept-Language` works too.","schema":{"type":"string","enum":["en","ko","ja","zh"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/PrivateErrand"}}}}}},"400":{"description":"The request breaks a rule","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Sign-in missing or expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed for your role","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such errand","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Not allowed in the current status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["hours"],"properties":{"hours":{"type":"integer","minimum":1,"maximum":336},"txHash":{"type":"string","description":"With the real escrow: the `extendReview` transaction"}}}}}}}},"/private/errands/{id}/ask":{"post":{"operationId":"askQuestion","summary":"Ask the client a multiple-choice question","description":"Chosen provider only, while funded. There is no free chat: the client picks one of your options with `respondToRequest`. Only one request waits for an answer at a time, and you cannot submit proof while one waits.","tags":["private"],"security":[{"wallet":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"lang","in":"query","required":false,"description":"Language of messages and sample texts. `Accept-Language` works too.","schema":{"type":"string","enum":["en","ko","ja","zh"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/PrivateErrand"}}}}}},"400":{"description":"The request breaks a rule","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Sign-in missing or expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed for your role","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such errand","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Not allowed in the current status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["topic","options"],"properties":{"topic":{"type":"string","enum":["item","option","place","time","other"]},"options":{"type":"array","minItems":2,"maxItems":4,"items":{"type":"string","maxLength":40}}}}}}}}},"/private/errands/{id}/defect":{"post":{"operationId":"reportDefect","summary":"Show the client a defect and ask whether to go on","description":"Chosen provider only, while funded. The client answers `proceed` or `decline`. After `proceed` the defect cannot be used as a reason to object later (`defectAccepted`).","tags":["private"],"security":[{"wallet":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"lang","in":"query","required":false,"description":"Language of messages and sample texts. `Accept-Language` works too.","schema":{"type":"string","enum":["en","ko","ja","zh"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/PrivateErrand"}}}}}},"400":{"description":"The request breaks a rule","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Sign-in missing or expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed for your role","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such errand","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Not allowed in the current status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["defect","photos"],"properties":{"defect":{"type":"string","enum":["scratch","crease","stain","box","display","other"]},"photos":{"type":"array","minItems":1,"maxItems":3,"items":{"type":"string"}}}}}}}}},"/private/errands/{id}/alternative":{"post":{"operationId":"proposeAlternative","summary":"Propose a substitute item","description":"Chosen provider only, while funded. The client answers `approve` or `reject`.","tags":["private"],"security":[{"wallet":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"lang","in":"query","required":false,"description":"Language of messages and sample texts. `Accept-Language` works too.","schema":{"type":"string","enum":["en","ko","ja","zh"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/PrivateErrand"}}}}}},"400":{"description":"The request breaks a rule","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Sign-in missing or expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed for your role","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such errand","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Not allowed in the current status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["note","photos"],"properties":{"note":{"type":"string","maxLength":80},"photos":{"type":"array","minItems":1,"maxItems":3,"items":{"type":"string"}}}}}}}}},"/private/errands/{id}/cancel":{"post":{"operationId":"requestCancel","summary":"Ask to cancel by agreement, without blame","description":"Client or chosen provider, while funded. The other side answers with `respondToRequest`; `accept` ends the errand as `cancelled` and the client is refunded in full.","tags":["private"],"security":[{"wallet":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"lang","in":"query","required":false,"description":"Language of messages and sample texts. `Accept-Language` works too.","schema":{"type":"string","enum":["en","ko","ja","zh"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/PrivateErrand"}}}}}},"400":{"description":"The request breaks a rule","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Sign-in missing or expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed for your role","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such errand","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Not allowed in the current status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["reason"],"properties":{"reason":{"type":"string","enum":["unavailable","closed","disaster","changed","other"]}}}}}}}},"/private/errands/{id}/request-address":{"post":{"operationId":"requestAddress","summary":"Ask the client to show the shipping address","description":"Chosen provider only, while funded, for an errand whose client attached an address. The client answers with `respondToRequest` (`approve` or `decline`); after `approve` the address can be read for 1 hour with `getAddress`, then it is hidden again and needs a new approval.","tags":["private"],"security":[{"wallet":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"lang","in":"query","required":false,"description":"Language of messages and sample texts. `Accept-Language` works too.","schema":{"type":"string","enum":["en","ko","ja","zh"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/PrivateErrand"}}}}}},"400":{"description":"The request breaks a rule","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Sign-in missing or expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed for your role","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such errand","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Not allowed in the current status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/private/errands/{id}/address":{"get":{"operationId":"getAddress","summary":"Read the shipping address","description":"The client can read it any time. The chosen provider can read it only while a window the client opened is open (`address.canView`, `address.expiresAt`); otherwise `error.addressBlind`. It is erased when the errand is paid or cancelled.","tags":["private"],"security":[{"wallet":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"lang","in":"query","required":false,"description":"Language of messages and sample texts. `Accept-Language` works too.","schema":{"type":"string","enum":["en","ko","ja","zh"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"object","properties":{"address":{"type":"string"},"expiresAt":{"type":["integer","null"]}}}}}}}},"400":{"description":"The request breaks a rule","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Sign-in missing or expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed for your role","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such errand","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Not allowed in the current status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/private/errands/{id}/respond":{"post":{"operationId":"respondToRequest","summary":"Answer the waiting request","description":"The side that did not ask. `choice` (index) answers a question; `decision` answers the rest: `proceed`/`decline` (defect), `approve`/`reject` (alternative), `accept`/`decline` (cancel). Once the escrow is live, accepting a cancel needs the refund `txHash`.","tags":["private"],"security":[{"wallet":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"lang","in":"query","required":false,"description":"Language of messages and sample texts. `Accept-Language` works too.","schema":{"type":"string","enum":["en","ko","ja","zh"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/PrivateErrand"}}}}}},"400":{"description":"The request breaks a rule","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Sign-in missing or expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed for your role","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such errand","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Not allowed in the current status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["request"],"properties":{"request":{"type":"string"},"choice":{"type":"integer","minimum":0},"decision":{"type":"string"},"txHash":{"type":"string"}}}}}}}},"/private/profile":{"get":{"operationId":"getMyProfile","summary":"My provider profile","tags":["private"],"security":[{"wallet":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"oneOf":[{"$ref":"#/components/schemas/Profile"},{"type":"null"}]}}}}}},"401":{"description":"Sign-in missing or expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"saveMyProfile","summary":"Save my provider profile","description":"Send all three lists; they may be empty. Clients see the profile next to your record when they choose.","tags":["private"],"security":[{"wallet":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["areas","categories","languages"],"properties":{"areas":{"type":"array","items":{"$ref":"#/components/schemas/Country"}},"categories":{"type":"array","items":{"$ref":"#/components/schemas/Category"}},"languages":{"type":"array","items":{"type":"string","enum":["en","ko","ja","zh"]}}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Profile"}}}}}},"400":{"description":"The request breaks a rule","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Sign-in missing or expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/private/invite":{"post":{"operationId":"redeemInvite","summary":"Spend an invite code","description":"Body `{code}`. Lets this wallet apply to the kinds of errand that need an invite (`error.inviteRequired` otherwise). The code works once and is gone after; a wallet that is already in keeps it unspent.","tags":["private"],"security":[{"wallet":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["code"],"properties":{"code":{"type":"string","maxLength":40}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"object","properties":{"invited":{"type":"boolean"}}}}}}}},"400":{"description":"The request breaks a rule","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Sign-in missing or expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/private/admin/invites":{"get":{"operationId":"listInvites","summary":"Admin: invite codes not used yet","description":"Wallets in `ERRAND_ADMINS` only. The codes themselves are not shown again.","tags":["private"],"security":[{"wallet":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Invite"}}}}}}},"401":{"description":"Sign-in missing or expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed for your role","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"createInvite","summary":"Admin: issue a one-time invite code","description":"Wallets in `ERRAND_ADMINS` only. Body `{note?}`. The answer holds the `code`; it is shown once and only a hash is kept.","tags":["private"],"security":[{"wallet":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"note":{"type":"string","maxLength":100}}}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"allOf":[{"$ref":"#/components/schemas/Invite"},{"type":"object","properties":{"code":{"type":"string"}}}]}}}}}},"403":{"description":"Not allowed for your role","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/private/admin/invites/{id}":{"delete":{"operationId":"revokeInvite","summary":"Admin: cancel an unused invite code","description":"Wallets in `ERRAND_ADMINS` only. Returns the codes that are left.","tags":["private"],"security":[{"wallet":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Invite"}}}}}}},"403":{"description":"Not allowed for your role","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/private/admin/suspensions":{"get":{"operationId":"listSuspensions","summary":"Admin: wallets kept from applying","description":"Wallets in `ERRAND_ADMINS` only.","tags":["private"],"security":[{"wallet":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Suspension"}}}}}}},"401":{"description":"Sign-in missing or expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed for your role","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"suspendWallet","summary":"Admin: keep a wallet from applying, or lift it","description":"Wallets in `ERRAND_ADMINS` only. A suspended wallet gets `error.suspended` when it applies, posts or objects. Errands already running are not touched, and neither is the escrow. A decision with `fraud: true` suspends the loser by itself.","tags":["private"],"security":[{"wallet":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["address","suspended"],"properties":{"address":{"type":"string","pattern":"^0x[0-9a-fA-F]{40}$","description":"Wallet address"},"suspended":{"type":"boolean"},"reason":{"type":"string","maxLength":300}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Suspension"}}}}}}},"400":{"description":"The request breaks a rule","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed for your role","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/private/notifications":{"get":{"operationId":"listNotifications","summary":"My notifications, newest first","description":"One for each step that concerns me: a new applicant, chosen, funded, proof submitted (`submittedLate` when it came within 12 hours of the end of the due day or later: look closely, or add time), time to check ending soon (for buying, `receiptCheck` a day before: prepare an objection if the goods have not come, as payment goes to the provider on its own), paid, cancelled, time extended, a request or its answer, and review results. `message` is written in the asked language; open the errand at `/errands/{errandId}`. You are not told about your own steps.","tags":["private"],"security":[{"wallet":[]}],"parameters":[{"name":"unread","in":"query","required":false,"schema":{"type":"string","enum":["1"]}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1}},{"name":"pageSize","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":50,"default":12}},{"name":"lang","in":"query","required":false,"description":"Language of messages and sample texts. `Accept-Language` works too.","schema":{"type":"string","enum":["en","ko","ja","zh"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/NotificationList"}}}}}},"401":{"description":"Sign-in missing or expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/private/notifications/read":{"post":{"operationId":"markNotificationsRead","summary":"Mark notifications read","description":"Without `ids`, all of them. Returns the number still unread.","tags":["private"],"security":[{"wallet":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"ids":{"type":"array","items":{"type":"string"}}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"object","properties":{"unread":{"type":"integer"}}}}}}}},"401":{"description":"Sign-in missing or expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/private/notifications/settings":{"get":{"operationId":"getNotificationSettings","summary":"Which kinds of notification I get","tags":["private"],"security":[{"wallet":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/NotificationSettings"}}}}}},"401":{"description":"Sign-in missing or expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"setNotificationSettings","summary":"Turn kinds of notification off or on","description":"`muted` is the full list of kinds to stop getting; send an empty list to get all.","tags":["private"],"security":[{"wallet":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["muted"],"properties":{"muted":{"type":"array","items":{"type":"string","enum":["applicant","chosen","funded","submitted","submittedLate","proofPending","reviewEnding","receiptCheck","paid","gift","cancelled","extended","request","answer","moderation","disputeOpened","disputeExtended","disputeDecided","adminReview","adminDeadline","adminHeld","unboxing"]}}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/NotificationSettings"}}}}}},"400":{"description":"The request breaks a rule","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Sign-in missing or expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/private/admin/errands":{"get":{"operationId":"listHeldErrands","summary":"Admin: errands held for review","description":"Wallets in `ERRAND_ADMINS` only. Errands whose texts the AI check marked `review`, oldest first.","tags":["private"],"security":[{"wallet":[]}],"parameters":[{"name":"lang","in":"query","required":false,"description":"Language of messages and sample texts. `Accept-Language` works too.","schema":{"type":"string","enum":["en","ko","ja","zh"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/PrivateErrand"}}}}}}},"401":{"description":"Sign-in missing or expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed for your role","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/private/admin/errands/{id}/decision":{"post":{"operationId":"decideHeldErrand","summary":"Admin: approve or reject a held errand","description":"Wallets in `ERRAND_ADMINS` only. Approve shows the errand in the public list; reject keeps it hidden and shows the client the reason.","tags":["private"],"security":[{"wallet":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"lang","in":"query","required":false,"description":"Language of messages and sample texts. `Accept-Language` works too.","schema":{"type":"string","enum":["en","ko","ja","zh"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/PrivateErrand"}}}}}},"400":{"description":"The request breaks a rule","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Sign-in missing or expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed for your role","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such errand","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Not allowed in the current status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["decision"],"properties":{"decision":{"type":"string","enum":["approve","reject"]},"reason":{"type":"string","maxLength":300}}}}}}}},"/private/admin/disputes":{"get":{"operationId":"listDisputes","summary":"Admin: objections","description":"Wallets in `ERRAND_ADMINS` only. Objections, those waiting for a decision first, with the checklist and the proposal.","tags":["private"],"security":[{"wallet":[]}],"parameters":[{"name":"lang","in":"query","required":false,"description":"Language of messages and sample texts. `Accept-Language` works too.","schema":{"type":"string","enum":["en","ko","ja","zh"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/PrivateErrand"}}}}}}},"401":{"description":"Sign-in missing or expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed for your role","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/private/admin/disputes/{id}/frames":{"get":{"operationId":"getDisputeFrames","summary":"Admin: the stills the AI looked at","description":"Wallets in `ERRAND_ADMINS` only. `?who=provider|client` picks the video. Returns `{frames}`: base64 JPEG stills in order, the ones the AI read (`P1`.. for the provider's video, `C1`.. for the client's), so the admin can check what a finding rests on.","tags":["private"],"security":[{"wallet":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"who","in":"query","required":true,"schema":{"type":"string","enum":["provider","client"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"object","properties":{"frames":{"type":"array","items":{"type":"string","description":"base64 JPEG"}}}}}}}}},"400":{"description":"The request breaks a rule","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Sign-in missing or expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed for your role","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such errand","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Not allowed in the current status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/private/admin/disputes/{id}/judge":{"post":{"operationId":"rejudgeDispute","summary":"Admin: have the AI read the videos again","description":"Wallets in `ERRAND_ADMINS` only, for a case in review. The AI only proposes; the admin decides.","tags":["private"],"security":[{"wallet":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"lang","in":"query","required":false,"description":"Language of messages and sample texts. `Accept-Language` works too.","schema":{"type":"string","enum":["en","ko","ja","zh"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/PrivateErrand"}}}}}},"400":{"description":"The request breaks a rule","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Sign-in missing or expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed for your role","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such errand","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Not allowed in the current status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/private/admin/disputes/{id}/decision":{"post":{"operationId":"decideDispute","summary":"Admin: decide an objection","description":"Wallets in `ERRAND_ADMINS` only. All one way: `provider` pays the provider, `client` refunds the client.","tags":["private"],"security":[{"wallet":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"lang","in":"query","required":false,"description":"Language of messages and sample texts. `Accept-Language` works too.","schema":{"type":"string","enum":["en","ko","ja","zh"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/PrivateErrand"}}}}}},"400":{"description":"The request breaks a rule","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Sign-in missing or expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed for your role","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such errand","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Not allowed in the current status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["winner"],"properties":{"winner":{"type":"string","enum":["provider","client"]},"note":{"type":"string","maxLength":1000}}}}}}}},"/private/errands/{id}/sync":{"post":{"operationId":"syncErrand","summary":"Read the errand's job from the network now","description":"Client or chosen provider. With the real escrow, brings the errand in line with its job (paid, cancelled, the real end of the time to check) and returns it. Call it after a wallet transaction. A payment that goes out on its own is also picked up by the server's timer.","tags":["private"],"security":[{"wallet":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"lang","in":"query","required":false,"description":"Language of messages and sample texts. `Accept-Language` works too.","schema":{"type":"string","enum":["en","ko","ja","zh"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/PrivateErrand"}}}}}},"400":{"description":"The request breaks a rule","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Sign-in missing or expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed for your role","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such errand","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Not allowed in the current status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/private/errands/{id}/trial/submit-as-provider":{"post":{"operationId":"trialSubmitAsProvider","summary":"Trial only: act as the provider","description":"Client only, while funded. Submits sample proof so one person can try the whole flow.","tags":["private"],"security":[{"wallet":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"lang","in":"query","required":false,"description":"Language of messages and sample texts. `Accept-Language` works too.","schema":{"type":"string","enum":["en","ko","ja","zh"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/PrivateErrand"}}}}}},"400":{"description":"The request breaks a rule","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Sign-in missing or expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed for your role","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such errand","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Not allowed in the current status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"securitySchemes":{"wallet":{"type":"http","scheme":"bearer","description":"Token from `signIn`. Valid for 24 hours."}},"schemas":{"Video":{"type":"object","description":"A proof video as the screens see it. The file is read with `getVideo`","properties":{"bytes":{"type":"integer"},"sha256":{"type":"string","description":"SHA-256 of the video as it arrived; part of the proof hash"},"mime":{"type":"string"},"code":{"type":"string","description":"The code the provider showed in the video"},"seconds":{"type":["integer","null"]},"at":{"type":"integer"},"erased":{"type":"boolean","description":"True once the file was erased after the keeping time"},"held":{"type":"boolean","description":"True while only the fingerprint is on the server; the provider keeps the file and sends it if the client objects"}}},"Status":{"type":"string","enum":["open","funded","submitted","paid","cancelled"]},"Dispute":{"type":"object","properties":{"state":{"type":"string","enum":["evidence","review","decided"]},"reason":{"type":"string","enum":["notArrived","notMatching","damaged","other"]},"note":{"type":"string"},"openedAt":{"type":"integer"},"depositUsd":{"type":"number","description":"The fee for the arbiter. Only recorded in trial"},"evidenceDueAt":{"type":"integer","description":"The client sends evidence before this (ms)"},"decideBy":{"type":"integer","description":"With no decision by then the deadline moves once by `meta.dispute.extendDays`, then the provider is paid (ms)"},"extendedAt":{"type":["integer","null"],"description":"When the deadline was moved (ms), or null"},"clientVideo":{"oneOf":[{"$ref":"#/components/schemas/Video"},{"type":"null"}]},"evidenceAt":{"type":["integer","null"]},"proposal":{"description":"Admins only. `winner` is null when a person has to watch the videos","oneOf":[{"type":"object","properties":{"winner":{"type":["string","null"],"enum":["provider","client",null]},"checks":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string","enum":["clientVideo","inTime","providerVideo","receipt","tracking"]},"ok":{"type":["boolean","null"]}}}},"at":{"type":"integer"}}},{"type":"null"}]},"ai":{"description":"Admins only. The AI reading of the two videos; it only proposes. `summary` and the notes are shown in the asked language (the AI writes all four and the server keeps all four)","oneOf":[{"type":"object","properties":{"state":{"type":"string","enum":["pending","done","failed"]},"winner":{"type":["string","null"],"enum":["provider","client",null]},"confidence":{"type":["string","null"],"enum":["high","medium","low",null]},"findings":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string","enum":["waybill","codeDate","sealed","opening","oneTake"]},"ok":{"type":["boolean","null"]},"note":{"type":"string"},"frames":{"type":"array","items":{"type":"string","example":"P3"}}}}},"summary":{"type":"string"},"stills":{"type":"string","enum":["saved","erased","none"],"description":"Whether the stills the AI read are kept (they go with the videos after the keeping time)"},"model":{"type":"string"},"usage":{"description":"Tokens the reading used, for the cost record","oneOf":[{"type":"object","properties":{"inputTokens":{"type":"integer"},"outputTokens":{"type":"integer"}}},{"type":"null"}]},"at":{"type":"integer"}}},{"type":"null"}]},"decision":{"oneOf":[{"type":"object","properties":{"winner":{"type":"string","enum":["provider","client"]},"byDefault":{"type":"boolean"},"at":{"type":"integer"},"note":{"type":"string"}}},{"type":"null"}]}}},"GoodsItem":{"type":"object","properties":{"id":{"type":"string"},"label":{"type":"string"},"note":{"type":"string"}}},"Category":{"type":"string","enum":["buy","check","ship"]},"Country":{"type":"string","enum":["jp","kr","us","cn","vn","th","tw","ph","other"]},"Proof":{"type":"string","enum":["receipt","item","tracking","video"]},"Action":{"type":"string","enum":["apply","choose","fund","submit","confirm","extend","object","dispute/evidence","ask","defect","alternative","cancel","respond","request-address","trial/submit-as-provider"]},"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","examples":["error.notOpen"]},"message":{"type":"string"},"vars":{"type":"object"}}}}},"Rates":{"type":"object","properties":{"JPY":{"type":"number","description":"Yen for one US dollar"},"KRW":{"type":"number","description":"Won for one US dollar"},"source":{"type":"string","enum":["live","fallback"]},"updatedAt":{"type":"string"}}},"Meta":{"type":"object","properties":{"version":{"type":"string"},"trial":{"type":"boolean"},"chainId":{"type":"integer"},"escrow":{"type":"object","properties":{"instance":{"type":"string","pattern":"^0x[0-9a-fA-F]{40}$","description":"Wallet address"},"evaluator":{"type":"string","pattern":"^0x[0-9a-fA-F]{40}$","description":"Wallet address"},"usdc":{"type":"string","pattern":"^0x[0-9a-fA-F]{40}$","description":"Wallet address"},"factory":{"type":"string","pattern":"^0x[0-9a-fA-F]{40}$","description":"Wallet address"}}},"arbitersAvailable":{"type":"boolean"},"fee":{"type":"object","description":"The service fee: `percent` of an errand's amount, taken from the provider's payment (the client pays exactly the amount). `charged` is whether the escrow in use really takes it: false in the trial and on an instance set up without the fee","properties":{"percent":{"type":"number"},"charged":{"type":"boolean"}}},"invite":{"type":"object","description":"Errand kinds only invited wallets may apply to. Spend a code with `redeemInvite`; `getMe` shows `invited`","properties":{"categories":{"type":"array","items":{"$ref":"#/components/schemas/Category"}}}},"goods":{"type":"object","description":"What may be bought (buying errands): allowed goods, goods left out for now, and forbidden goods, in the asked language. Texts that name goods of the last two groups are refused; the rest is judged by the AI check","properties":{"buy":{"type":"object","properties":{"requireAi":{"type":"boolean"},"allowed":{"type":"array","items":{"$ref":"#/components/schemas/GoodsItem"}},"notYet":{"type":"array","items":{"$ref":"#/components/schemas/GoodsItem"}},"forbidden":{"type":"array","items":{"$ref":"#/components/schemas/GoodsItem"}}}}}},"dispute":{"type":"object","description":"The objection process: categories that allow it, the fee, the times","properties":{"categories":{"type":"array","items":{"$ref":"#/components/schemas/Category"}},"deposit":{"type":"object","properties":{"percent":{"type":"number"},"minUsd":{"type":"number"},"maxUsd":{"type":"number"}}},"evidenceHours":{"type":"integer"},"decideDays":{"type":"integer"},"extendDays":{"type":"integer"},"reasons":{"type":"array","items":{"type":"string"}}}},"evidence":{"type":"object","description":"Proof videos kept on the server; `available` is false until the server has a key for them","properties":{"available":{"type":"boolean"},"maxBytes":{"type":"integer"},"maxSeconds":{"type":"integer"},"types":{"type":"array","items":{"type":"string"}},"keepDays":{"type":"integer"}}},"limits":{"type":"object"},"categories":{"type":"array","items":{"$ref":"#/components/schemas/Category"}},"openCategories":{"type":"array","items":{"$ref":"#/components/schemas/Category"},"description":"Categories that can be posted now. `buy` is closed until arbiters exist"},"previewCategories":{"type":"array","items":{"$ref":"#/components/schemas/Category"},"description":"Categories closed for everyone while the real escrow cannot carry their objections, that an administrator or a wallet that spent an invite code may still post on a test network (never on the main network). Empty otherwise"},"countries":{"type":"array","items":{"$ref":"#/components/schemas/Country"}},"openCountries":{"type":"array","items":{"$ref":"#/components/schemas/Country"},"description":"Countries that can be posted now. The pilot starts with `jp` and `kr`"},"proofs":{"type":"array","items":{"$ref":"#/components/schemas/Proof"}},"requiredProofs":{"type":"object","description":"Proof a category always needs, whatever the client ticks, by category","additionalProperties":{"type":"array","items":{"$ref":"#/components/schemas/Proof"}}},"statuses":{"type":"array","items":{"$ref":"#/components/schemas/Status"}},"locales":{"type":"array","items":{"type":"string"}},"templates":{"type":"array","description":"Preset errands in the asked language. Copy one into `createErrand` (due date = today + `dueDays`), change what you need and pass its `id` as `templateId`","items":{"$ref":"#/components/schemas/Template"}}}},"Template":{"type":"object","properties":{"id":{"type":"string"},"category":{"$ref":"#/components/schemas/Category"},"countries":{"type":"array","items":{"$ref":"#/components/schemas/Country"},"description":"Empty: any open country"},"label":{"type":"string","description":"Short label for a button"},"title":{"type":"string"},"detail":{"type":"string","description":"A guide to fill in, line by line"},"proofs":{"type":"array","items":{"$ref":"#/components/schemas/Proof"}},"amountUsd":{"type":"number"},"dueDays":{"type":"integer"},"reviewHours":{"type":"integer"},"maxExtensionHours":{"type":"integer"}}},"PublicErrand":{"type":"object","properties":{"id":{"type":"string"},"status":{"$ref":"#/components/schemas/Status"},"category":{"$ref":"#/components/schemas/Category"},"country":{"$ref":"#/components/schemas/Country"},"city":{"type":"string"},"title":{"type":"string"},"detail":{"type":"string"},"amountUsd":{"type":"number"},"dueDate":{"type":"string","format":"date"},"proofs":{"type":"array","items":{"$ref":"#/components/schemas/Proof"}},"client":{"type":"string","pattern":"^0x[0-9a-fA-F]{40}$","description":"Wallet address"},"provider":{"oneOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{40}$","description":"Wallet address"},{"type":"null"}]},"arbiter":{"oneOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{40}$","description":"Wallet address"},{"type":"null"}],"description":"Null until arbiters open"},"applicantCount":{"type":"integer"},"createdAt":{"type":"integer","description":"ms since epoch"},"fundedAt":{"type":["integer","null"]},"paidAt":{"type":["integer","null"]},"chosenAt":{"type":["integer","null"]},"cancelledAt":{"type":["integer","null"]},"reviewHours":{"type":"integer","description":"Time to check after submission, set by the client"},"maxExtensionHours":{"type":"integer","description":"Most hours the client may add once"},"extendedHours":{"type":["integer","null"]},"reviewEndsAt":{"type":["integer","null"],"description":"When payment goes out, extension included"},"lastMinute":{"type":"boolean","description":"The proof came within 12 hours of the end of the due day, or after it. The time to check is not shorter for it; the client is told to look closely"},"sample":{"type":"boolean"},"templateId":{"type":["string","null"]},"sourceLang":{"type":"string","enum":["en","ko","ja","zh","other"],"description":"Language `title` and `detail` were written in, judged from the characters"},"translation":{"description":"`title`, `detail` and `city` automatically translated into the asked language (`?lang=`). The originals above stay the source of truth. Null when not needed or not ready (no engine, or still being made)","oneOf":[{"type":"object","properties":{"lang":{"type":"string","enum":["en","ko","ja","zh"]},"title":{"type":"string"},"detail":{"type":"string"},"city":{"type":"string"}}},{"type":"null"}]}}},"PrivateErrand":{"allOf":[{"$ref":"#/components/schemas/PublicErrand"},{"type":"object","properties":{"role":{"type":"string","enum":["owner","provider","applicant","visitor"]},"actions":{"type":"array","items":{"$ref":"#/components/schemas/Action"}},"applicants":{"type":"array","items":{"type":"object","properties":{"address":{"type":"string","pattern":"^0x[0-9a-fA-F]{40}$","description":"Wallet address"},"city":{"type":"string"},"completed":{"type":"integer"},"reputation":{"$ref":"#/components/schemas/Reputation"},"profile":{"oneOf":[{"$ref":"#/components/schemas/Profile"},{"type":"null"}]},"message":{"type":"string"},"translation":{"type":["string","null"],"description":"`message` in the asked language"},"sample":{"type":"boolean"}}}},"submission":{"oneOf":[{"type":"object","properties":{"photos":{"type":"array","items":{"type":"string"}},"tracking":{"type":"string"},"memo":{"type":"string"},"memoTranslation":{"type":["string","null"]},"video":{"description":"The proof video, when the errand asks for one","oneOf":[{"$ref":"#/components/schemas/Video"},{"type":"null"}]},"at":{"type":"integer"}}},{"type":"null"}]},"stagedDigest":{"type":["string","null"],"description":"Provider only. The digest of the proof the server holds (`stageProof`), to put on the escrow; null before"},"pendingVideo":{"description":"Uploaded by the provider, not yet submitted. Provider only","oneOf":[{"$ref":"#/components/schemas/Video"},{"type":"null"}]},"dispute":{"description":"The client's objection and how it went (client, provider and admins). `proposal` is for admins only","oneOf":[{"$ref":"#/components/schemas/Dispute"},{"type":"null"}]},"disputeVideoCode":{"type":["string","null"],"description":"The 4-digit code the client shows in the unboxing video, for today. Given while the client checks a buying errand and while evidence is due. A video filmed on an earlier day carries that day's code (any day since the proof came in is accepted). Client only"},"videoCode":{"type":["string","null"],"description":"The 4-digit code the provider shows in the video today, while the errand waits for proof. Provider only"},"requests":{"type":"array","description":"Structured requests, oldest first (client and provider only). Only the fields of the request's `kind` are filled","items":{"$ref":"#/components/schemas/Request"}},"chain":{"description":"The escrow job behind the errand once funded on the real escrow, else null","oneOf":[{"type":"object","properties":{"instance":{"type":"string","pattern":"^0x[0-9a-fA-F]{40}$","description":"Wallet address"},"jobId":{"type":"string"},"submittedOnChain":{"type":"boolean","description":"The provider submitted on the network but the proof is not uploaded yet"},"submitBy":{"type":["integer","null"],"description":"Provider's deadline to submit (ms)"}}},{"type":"null"}]},"address":{"type":"object","description":"The shipping address as the caller may see it. The address itself is only in `getAddress`","properties":{"protected":{"type":"boolean","description":"The client attached an address"},"canView":{"type":"boolean"},"expiresAt":{"type":["integer","null"],"description":"When the provider's window closes"}}},"defectAccepted":{"type":"boolean","description":"The client agreed to go ahead with a defect"},"moderation":{"description":"The text check's decision, for the client and admins. `review`: hidden from the public list until an admin approves; `rejected`: turned down","oneOf":[{"type":"object","properties":{"verdict":{"type":"string","enum":["ok","review","rejected"]},"reason":{"type":"string"},"source":{"type":"string","enum":["rules","ai","admin"]},"at":{"type":"integer"}}},{"type":"null"}]}}}]},"Profile":{"type":"object","properties":{"areas":{"type":"array","items":{"$ref":"#/components/schemas/Country"}},"categories":{"type":"array","items":{"$ref":"#/components/schemas/Category"}},"languages":{"type":"array","items":{"type":"string","enum":["en","ko","ja","zh"]}},"updatedAt":{"type":"integer"}}},"Reputation":{"type":"object","description":"Counted from the errands, never stored. Sample wallets show zeros","properties":{"completed":{"type":"integer","description":"Paid, as the provider"},"onTime":{"type":"integer","description":"Of those, proof in by the due date (12 hours of grace)"},"cancelled":{"type":"integer","description":"Cancelled by agreement. Never a penalty"},"active":{"type":"integer"}}},"Provider":{"type":"object","properties":{"address":{"type":"string","pattern":"^0x[0-9a-fA-F]{40}$","description":"Wallet address"},"profile":{"oneOf":[{"$ref":"#/components/schemas/Profile"},{"type":"null"}]},"reputation":{"$ref":"#/components/schemas/Reputation"},"suspended":{"type":"boolean"}}},"Invite":{"type":"object","properties":{"id":{"type":"string"},"note":{"type":"string"},"at":{"type":"integer"},"by":{"type":"string","pattern":"^0x[0-9a-fA-F]{40}$","description":"Wallet address"}}},"Suspension":{"type":"object","properties":{"address":{"type":"string","pattern":"^0x[0-9a-fA-F]{40}$","description":"Wallet address"},"reason":{"type":"string"},"at":{"type":"integer"},"by":{"type":"string","pattern":"^0x[0-9a-fA-F]{40}$","description":"Wallet address"}}},"NotificationList":{"type":"object","properties":{"total":{"type":"integer"},"page":{"type":"integer"},"pageSize":{"type":"integer"},"pages":{"type":"integer"},"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"kind":{"type":"string","enum":["applicant","chosen","funded","submitted","submittedLate","proofPending","reviewEnding","receiptCheck","paid","gift","cancelled","extended","request","answer","moderation","disputeOpened","disputeExtended","disputeDecided","adminReview","adminDeadline","adminHeld","unboxing"]},"errandId":{"type":"string"},"errandTitle":{"type":"string"},"message":{"type":"string","description":"The sentence, in the asked language"},"at":{"type":"integer"},"read":{"type":"boolean"},"request":{"type":["string","null"],"description":"For `request` and `answer`: question, defect, alternative or cancel"}}}},"unread":{"type":"integer"}}},"NotificationSettings":{"type":"object","properties":{"kinds":{"type":"array","items":{"type":"string","enum":["applicant","chosen","funded","submitted","submittedLate","proofPending","reviewEnding","receiptCheck","paid","gift","cancelled","extended","request","answer","moderation","disputeOpened","disputeExtended","disputeDecided","adminReview","adminDeadline","adminHeld","unboxing"]}},"muted":{"type":"array","items":{"type":"string","enum":["applicant","chosen","funded","submitted","submittedLate","proofPending","reviewEnding","receiptCheck","paid","gift","cancelled","extended","request","answer","moderation","disputeOpened","disputeExtended","disputeDecided","adminReview","adminDeadline","adminHeld","unboxing"]}}}},"Request":{"type":"object","properties":{"id":{"type":"string"},"kind":{"type":"string","enum":["question","defect","alternative","cancel","address"]},"by":{"type":"string","pattern":"^0x[0-9a-fA-F]{40}$","description":"Wallet address"},"byRole":{"type":"string","enum":["owner","provider"]},"at":{"type":"integer"},"pending":{"type":"boolean","description":"Waiting for the other side's answer"},"answeredAt":{"type":["integer","null"]},"topic":{"type":["string","null"],"enum":["item","option","place","time","other",null]},"options":{"type":"array","items":{"type":"string"}},"choice":{"type":["integer","null"],"description":"Index of the option picked"},"defect":{"type":["string","null"],"enum":["scratch","crease","stain","box","display","other",null]},"note":{"type":"string"},"photos":{"type":"array","items":{"type":"string"}},"reason":{"type":["string","null"],"enum":["unavailable","closed","disaster","changed","other",null]},"decision":{"type":["string","null"]},"translation":{"description":"`note` and `options` in the asked language, or null","oneOf":[{"type":"object","properties":{"note":{"type":"string"},"options":{"type":"array","items":{"type":"string"}}}},{"type":"null"}]}}},"CreateErrand":{"type":"object","required":["title","category","country","dueDate","amountUsd","proofs"],"properties":{"title":{"type":"string","maxLength":80},"detail":{"type":"string"},"category":{"$ref":"#/components/schemas/Category"},"country":{"$ref":"#/components/schemas/Country"},"city":{"type":"string"},"dueDate":{"type":"string","format":"date","description":"Today or later"},"amountUsd":{"type":"number","minimum":1,"maximum":100},"proofs":{"type":"array","items":{"$ref":"#/components/schemas/Proof"}},"reviewHours":{"type":"integer","minimum":12,"maximum":336,"description":"Time to check after submission, at least 12 hours. Default 336 (14 days) for buying, 24 otherwise"},"maxExtensionHours":{"type":"integer","minimum":0,"maximum":336,"description":"Most hours the client may add once while checking. Default 168 for buying, 48 otherwise"},"templateId":{"type":"string","description":"The preset used, from `meta.templates`"},"shippingAddress":{"type":"string","maxLength":300,"description":"Optional. `ship` errands only, and only when `meta.addressProtection.available`. Kept encrypted, never translated or sent to the AI check, shown to the chosen provider only after you approve"}}},"Nonce":{"type":"object","properties":{"nonce":{"type":"string"},"domain":{"type":"string"},"uri":{"type":"string"},"chainId":{"type":"integer"},"statement":{"type":"string"}}},"Session":{"type":"object","properties":{"token":{"type":"string"},"address":{"type":"string","pattern":"^0x[0-9a-fA-F]{40}$","description":"Wallet address"},"expiresAt":{"type":"integer"}}},"Me":{"type":"object","properties":{"address":{"type":"string","pattern":"^0x[0-9a-fA-F]{40}$","description":"Wallet address"},"posted":{"type":"integer"},"providing":{"type":"integer"},"unreadNotifications":{"type":"integer"},"admin":{"type":"boolean","description":"True for wallets in `ERRAND_ADMINS`"},"applied":{"type":"integer"},"invited":{"type":"boolean","description":"True once this wallet spent an invite code"}}}}}}