@officexapp/vidfarm-devcli 0.21.62 → 0.21.64

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. package/.agents/skills/dollarplatoon-skill/SKILL.md +163 -1174
  2. package/.agents/skills/dollarplatoon-skill/SOURCE.md +62 -0
  3. package/.agents/skills/dollarplatoon-skill/skill/clients.md +234 -0
  4. package/.agents/skills/dollarplatoon-skill/skill/feeds.md +326 -0
  5. package/.agents/skills/dollarplatoon-skill/skill/gigs.md +395 -0
  6. package/.agents/skills/dollarplatoon-skill/skill/gigworkers.md +324 -0
  7. package/.agents/skills/dollarplatoon-skill/skill/orders.md +573 -0
  8. package/.agents/skills/dollarplatoon-skill/skill/payouts.md +234 -0
  9. package/.agents/skills/dollarplatoon-skill/skill/platform.md +174 -0
  10. package/.agents/skills/dollarplatoon-skill/skill/prices.md +75 -0
  11. package/.agents/skills/dollarplatoon-skill/skill/pricing-and-tags.md +255 -0
  12. package/.agents/skills/dollarplatoon-skill/skill/proofs.md +555 -0
  13. package/.agents/skills/dollarplatoon-skill/skill/queue.md +404 -0
  14. package/.agents/skills/dollarplatoon-skill/skill/quickstart.md +191 -0
  15. package/.agents/skills/dollarplatoon-skill/skill/staging.md +178 -0
  16. package/.agents/skills/dollarplatoon-skill/skill/tasks.md +588 -0
  17. package/.agents/skills/dollarplatoon-skill/skill/web-pages.md +586 -0
  18. package/.agents/skills/vidfarm/SKILL.md +3 -3
  19. package/.agents/skills/vidfarm/references/core-workflows.md +107 -3
  20. package/SKILL.director.md +109 -5
  21. package/SKILL.md +3 -1
  22. package/clipper.md +20 -0
  23. package/dist/src/cli.js +50 -6
  24. package/dist/src/devcli/delivery-seal.js +119 -0
  25. package/dist/src/devcli/marketplace-console.js +1418 -0
  26. package/dist/src/devcli/marketplace-gigs.js +162 -16
  27. package/marketplace.md +299 -1
  28. package/package.json +24 -3
@@ -1,1227 +1,216 @@
1
1
  ---
2
2
  name: dollarplatoon-skill
3
3
  description: >
4
- Peer-to-peer task payroll infrastructure on Base L2 for private work networks. Clients create
5
- USDC-funded gigs, invite gigworkers via invite links, distribute tasks via email/webhook
6
- mailboxes, review proofs of work, and pay out on-chain. Reputation-driven with no dispute
7
- resolution. Use when: (1) Creating gigs or joining via invite, (2) Submitting or reviewing
8
- proofs, (3) Managing wallets and payouts, (4) Understanding pricing or network dynamics,
9
- (5) Integrating via webhook or public submit link.
10
- Triggers: dollar platoon, gig payroll, micro-gig, proof review, rollup payout, volunteer mailbox,
11
- invite link, task distribution, reputation system, treasury contract, recommended prices, how it works.
4
+ Peer-to-peer task payroll on Base L2. Clients fund USDC gigs ("vending machines"), invite
5
+ gigworkers by link, push tasks to their mailboxes, review proofs of work, and pay out
6
+ on-chain. Gigworkers join by invite, poll or receive tasks, submit proofs, and get paid in
7
+ USDC. One mode inverts this: an "order machine" is a shop whose owner does the work, funded
8
+ per order by the buyer who places it. Settlement is recorded in an event ledger and nothing is
9
+ scored or rated; there is no dispute resolution and no public marketplace. Use this skill whenever the user mentions
10
+ dollarplatoon.com, Dollar Platoon, a "vending machine" for gig work, micro-gig payroll, paying
11
+ workers in USDC per task, proof review or approval, rollups and payouts, gig invite links,
12
+ worker mailboxes, task queues and polling, feeds of gigs, escrowing or pre-funding a task on
13
+ chain before it is worked, or placing and funding an order against a shop — and also when they
14
+ are building an agent that earns money doing tasks, or an agent that distributes tasks to
15
+ workers, even if they never name the platform.
16
+ Read this index first, then open only the linked file the task needs.
12
17
  ---
13
18
 
14
19
  # Dollar Platoon
15
20
 
16
- > **Install this app on OfficeX:** [officex.app/store/en/app/dollar-platoon](https://officex.app/store/en/app/dollar-platoon)
21
+ Peer-to-peer task payroll on Base L2. Clients fund gigs with USDC, invite gigworkers privately,
22
+ distribute tasks, review proofs, and pay out on-chain. High volume, low ticket, no contracts, no
23
+ dispute resolution.
17
24
 
18
- ## What Is Dollar Platoon?
25
+ **This file is an index.** It carries only what every task needs. Everything else lives in the
26
+ files mapped below — open the one your task needs and skip the rest.
19
27
 
20
- Peer-to-peer task payroll on Base L2. Private, reputation-driven work networks for high-volume, low-ticket work infrastructure, not a marketplace.
28
+ Links below are absolute URLs, so they work when this file is fetched from the web. **If you
29
+ already have these files on disk**, the same documents sit next to this one at `skill/<name>.md`
30
+ — read them from the filesystem instead of over the network. **If you fetched this file from
31
+ staging**, the same documents sit at `skill/<name>.md` on that host too; the links below point at
32
+ production's identical copy, so read siblings from the host you started on if that matters to you.
21
33
 
22
- Create micro-gigs, distribute tasks to gigworkers, collect proofs, and pay out USDC on Base L2. No contracts, no overhead, no dispute resolution — reputation is the sole enforcement mechanism.
23
-
24
- ### For Clients
25
-
26
- Scale your workforce instantly. Create gigs, distribute tasks to gigworkers, review proofs, and pay out USDC on Base L2.
27
-
28
- - **Create Gigs** — Post tasks with USDC funding. Set price per proof, review timeouts, and distribution mode.
29
- - **Review Proofs** — Approve or reject submissions with a single click. Auto-approve after timeout protects gigworkers.
30
- - **Track Payouts** — Monitor funds, trigger payouts, and view on-chain transaction history.
31
-
32
- ### For Gigworkers
33
-
34
- Earn USDC doing tasks. Join private gigs via invite links from clients, submit proofs of work, and get paid automatically on Base L2. Build your reputation as you go.
35
-
36
- - **Join by Invite** — Clients invite you into their private work networks with invite links. Join gigs that match your skills.
37
- - **Submit Proofs** — Complete tasks, submit evidence, and track your submissions across all your mailboxes.
38
- - **Build Reputation** — Every approved proof builds your on-chain reputation across Volume, Quality, and Social dimensions.
34
+ - **API base URL:** `https://dollarplatoon.com/api`
35
+ - **Auth:** an `x-api-key` header on every authenticated call. Get a key at
36
+ [dollarplatoon.com/settings](https://dollarplatoon.com/settings).
37
+ - **Staging:** `https://staging.dollarplatoon.com/api` — same code, Base Sepolia, its own
38
+ accounts, and the only stage where order machines exist. **Build here first:**
39
+ [skill/staging.md](https://dollarplatoon.com/skill/staging.md).
39
40
 
40
41
  ---
41
42
 
42
- ## How It Works
43
-
44
- Peer-to-peer task payroll on Base L2. Read this before creating or joining a gig.
45
-
46
- ### Overview
47
-
48
- Dollar Platoon is composable on-chain task payroll infrastructure for private peer-to-peer work networks. There is no public marketplace: each gig is a private network, and clients invite gigworkers via invite links. Clients create gigs and fund them with USDC on Base L2. Gigworkers join via invite, receive tasks, submit proofs of completed work, and get paid automatically when proofs are approved.
49
-
50
- The platform is designed for high-volume task payroll with no upper limit on price. There is no dispute resolution. Reputation is the sole enforcement mechanism.
51
-
52
- **The basic flow:**
53
-
54
- 1. Client creates a gig with terms, price per task, and USDC funding
55
- 2. Gigworkers join via the client's invite link and receive a personal mailbox
56
- 3. Tasks are distributed to mailboxes via email or webhook
57
- 4. Gigworkers submit proofs of completed work
58
- 5. Client reviews and approves/rejects proofs (or auto-approve after timeout)
59
- 6. Approved proofs trigger USDC payouts on Base L2
60
-
61
- ### Wallets & Gas
62
-
63
- Every user on Dollar Platoon has their own on-chain wallet on Base L2 (an Ethereum Layer 2 network). This wallet holds your USDC (for gig payments) and a small amount of ETH (for gas fees to process transactions).
64
-
65
- **Your responsibility:** Fund your wallet with ETH for gas on the Base network. Without ETH, your wallet cannot send transactions (deposits, transfers, or payouts). You typically need only ~0.001 ETH to cover many transactions.
66
-
67
- **Key Points:**
68
-
69
- - **Gas fees:** Every on-chain action requires a small ETH gas fee. Base L2 fees are typically fractions of a cent.
70
- - **Managed vs External:** Dollar Platoon can generate a managed (hot) wallet with encrypted key storage. Alternatively, link your own external wallet for full self-custody.
71
- - **No recovery:** If you lose access to an external wallet's private keys, those funds are permanently lost. Managed wallets are recoverable through your Dollar Platoon account.
72
-
73
- ### Reputation System
74
-
75
- Reputation is wallet-anchored, multi-dimensional, and event-sourced. Every action generates immutable reputation events tied to wallet addresses. Both clients and gigworkers have reputation.
76
-
77
- **Dimensions:**
78
-
79
- - **Volume** — Total USDC earned (gigworker) or paid out (client). The most basic measure of activity and trust.
80
- - **Quality** — Approval rate weighted by rejection severity. Fake proofs damage quality 5x more than low-quality work.
81
- - **Recency** — Decay function penalizing inactivity. Recent participants are more trustworthy than dormant ones.
82
- - **Social** — Aggregate star rating from counterparty reviews, weighted by dollar amount exchanged in each gig.
83
-
84
- **Key Features:**
85
-
86
- - **Wallet-anchored:** Reputation is tied to wallet addresses, not user accounts. Different wallets per gig means independent reputation histories.
87
- - **Permissionless:** Anyone can create a wallet and participate. Reputation must be earned.
88
- - **Gig gating:** Clients can set minimum reputation thresholds (min volume, min quality, min recency) to exclude low-reputation wallets.
89
- - **Informational only:** Reputation indicators are provided as informational aids. They carry no warranty of accuracy.
90
-
91
- ### Smart Contract & Payments
92
-
93
- Dollar Platoon uses a single treasury smart contract deployed on Base L2. The contract handles USDC deposits and payouts. All business logic (reputation, distribution, proof review) lives off-chain.
94
-
95
- **Fee Structure:**
96
-
97
- | Event | Fee | Detail |
98
- |-------|-----|--------|
99
- | Client deposits USDC | 0% | No deposit fee |
100
- | Gigworker payout | 10% on top | Worker receives full gross; 10% charged additionally from gig balance |
101
-
102
- Example: Worker earns $10 → contract charges $11 total ($10 to worker, $1 platform fee).
103
-
104
- **Key Features:**
105
-
106
- - **Fund isolation:** Each gig has its own on-chain balance. One gig's funds cannot pay out another.
107
- - **No withdrawal:** Once deposited, funds are locked in the gig. No withdrawal function exists.
108
- - **Price lock:** Price per task is locked at the moment of proof submission, protecting gigworkers from mid-gig price changes.
109
- - **Auto-approve timeout:** If a client does not review a proof within the review timeout period, the proof is automatically approved.
110
- - **Minimum payout:** Configurable per gig (default $0). Smaller amounts accumulate until threshold is met.
111
- - **No debt:** Gigs cannot go into debt. Rollups pre-check available_funds before payout.
112
-
113
- ### Security Tokens
114
-
115
- Every gig has a 6-character alphanumeric security token embedded in its email address and webhook URL. This prevents unauthorized submissions from anyone who discovers or guesses a gig ID.
116
-
117
- **How it works:**
118
-
119
- - **Email:** `{gig_id}_{token}.dollar-platoon@fwd.zoomgtm.com`
120
- - **Webhook:** `/inbound/webhook/{gig_id}?token={token}`
121
- - Inbound requests without a valid token are rejected with 403
122
- - Tokens are generated automatically on gig creation
123
- - Owners can rotate tokens via the dashboard or `POST /gigs/:id/rotate-token`
124
- - Rotating a token invalidates the old email address and webhook URL — update all integrations after rotating
125
- - **Backward compatibility:** Existing gigs without a security token will accept all inbound requests. Generate a token from the dashboard to enable protection.
126
-
127
- ### Third-Party Publisher Apps
128
-
129
- Dollar Platoon does not control task content or delivery. Tasks are generated and delivered by third-party publisher apps (or manually by clients). Every gig generates a token-protected inbound email address and webhook URL. Publisher apps send tasks to these endpoints, and Dollar Platoon distributes them to gigworker mailboxes.
130
-
131
- Dollar Platoon has no control over what publisher apps send. Clients are solely responsible for selecting and configuring their publisher apps. Gigworkers should review gig terms carefully before joining.
132
-
133
- ### Composability & Flexible Workflow
134
-
135
- Dollar Platoon handles only the payroll layer: distribution, proof collection, reputation, and payment. Everything else is pluggable:
136
-
137
- - **Task generation:** Use any publisher app, email client, or manual workflow
138
- - **Task delivery:** Email forwarding, webhook forwarding, or both
139
- - **Proof validation:** Manual client review, webhook-based automation, AI agents, or timeout auto-approval
140
- - **Distribution modes:** Round robin, random, priority weighted, free-for-all, FIFO queue, or inbound proof
141
- - **Reputation gating:** Set minimums per gig or leave open to all
142
-
143
- ### Trust & Validation
144
-
145
- Trust is earned, not granted. The reputation system provides signals but not guarantees.
146
-
147
- **For clients:** Review proofs carefully. Use rejection tags to flag bad work. Set reputation thresholds to filter applicants. Configure proof webhooks for automated validation. Consider requiring member approval for new joiners.
148
-
149
- **For gigworkers:** Check the client's reputation score before joining. Look at their volume, quality, and social ratings. Check the gig's available funds. Understand the review timeout period.
150
-
151
- **Highly recommended:** Extend trust validation with your own systems and AI agents. Use proof webhooks to validate submissions programmatically.
152
-
153
- ### As-Is Risk Nature
154
-
155
- Dollar Platoon is provided on an "as-is" and "as-available" basis. ZoomGTM operates it as a technology platform only. Smart contracts may contain bugs, blockchain networks may experience congestion, private keys can be lost permanently, and counterparties may act in bad faith despite reputation indicators.
156
-
157
- This is a permissionless system. All parties participate entirely at their own risk and expense.
158
-
159
- ### Liability Waiver
160
-
161
- By using Dollar Platoon, you irrevocably waive all claims against ZoomGTM and its affiliates. No dispute resolution. No warranties. Maximum aggregate liability: $0.
162
-
163
- ### Prohibited Uses
164
-
165
- Dollar Platoon may not be used for illegal activities, adult content, harassment, money laundering, malware distribution, circumventing sanctions, or high-risk financial services. ZoomGTM may suspend access at any time without notice. See full Terms of Use.
166
-
167
- ### Extending with Your Own Systems
168
-
169
- - **AI Agent Task Delivery (Recommended)** — Use the webhook endpoint to push tasks with dual-format HTML payloads. Human gigworkers see a clean UI with click-to-copy fields and action buttons. AI agents extract structured JSON from the hidden `div.agent-data`. One payload serves both audiences.
170
- - **AI Agent Review** — Configure proof webhooks to send submissions to your own AI agent for automated quality checks
171
- - **Custom Validation Pipelines** — Build webhook handlers that validate proofs against external data sources
172
- - **Publisher App Integration** — Build or use third-party publisher apps to generate tasks via webhook
173
- - **AI Agent Gigworking** — Set a webhook URL on your mailbox when joining a gig. Your agent receives tasks automatically, parses the agent-data JSON, completes the work, and submits proofs via the API — fully autonomous.
174
- - **Manual Workflow** — Email tasks to your gig address, review proofs in the dashboard, click approve/reject
43
+ ## "Vending machine" means gig
44
+
45
+ A **vending machine is a gig**. It is the colloquial name for the same object — when a user says
46
+ "vending machine", read "gig". There is no separate entity, resource, or endpoint: the API only
47
+ ever says gig (`/gigs`, `gig_id`).
48
+
49
+ The metaphor is exact. The client loads it with USDC. It holds gigworker mailboxes. A gigworker
50
+ puts in a proof of work and the machine pays out USDC. It runs on fixed rules — price per task,
51
+ review timeout, queue order without the client present.
52
+
53
+ | Colloquial | Actual object |
54
+ |---|---|
55
+ | Vending machine, machine | Gig |
56
+ | Loading / stocking the machine | Funding the gig, or adding tasks to its queue |
57
+ | Slot, dispenser | A gigworker's mailbox in the gig |
58
+ | Vending wall | A set of gigs shown together |
59
+ | Order machine, shop | A gig whose `distribution` is `inbound_order` — see below |
60
+
61
+ **One machine runs backwards, and it is called an order machine.** On a gig whose `distribution`
62
+ is `inbound_order`, the owner is the **vendor who does the work**, and an outside **participant**
63
+ sends the task, funds it with their own per-order USDC deposit, and is the only party who may
64
+ approve it. Every "the client sends work and pays for it" sentence in this skill is false there.
65
+ It is documented on its own page — [skill/orders.md](https://dollarplatoon.com/skill/orders.md) —
66
+ and the pages it contradicts say so where it matters.
67
+
68
+ **Your role is a property of the MACHINE, not of your session.** There is no client/worker toggle
69
+ and no persona in any URL: for each machine you are its Owner or a Participant in it. One account,
70
+ one set of pages. See [skill/web-pages.md](https://dollarplatoon.com/skill/web-pages.md).
71
+
72
+ **On screen it says Vending Machine; in the URL it says `gigs`.** The app's pages live at `/gigs`,
73
+ `/gigs/:id` and so on — the path follows the API and the entity, and the label follows the
74
+ product. Older `/machine*`, `/client/*` and `/gigworker/*` links all still redirect, carrying
75
+ their query string. Note that the SINGULAR `/gig/:id` is a different page: the public gig view,
76
+ with `/gig/:id/join?invite=` as its invite landing.
175
77
 
176
78
  ---
177
79
 
178
- ## Important Warnings & Best Practices
179
-
180
- ### Gig Funding
181
-
182
- - **Fund your gig before approving proofs.** Approved proofs cannot be paid if the gig has insufficient funds. The platform will reject the rollup.
183
- - **Account for the 10% platform fee.** A $100 payout costs $110 from the gig balance. When funding, budget 110% of expected payouts.
184
- - **Funds are locked.** There is no withdrawal function. Once USDC is deposited into a gig, it can only leave via worker payouts. Deposit conservatively and top up as needed.
185
- - **No debt allowed.** Rollups pre-check `available_funds >= gross_amount + platform_fee`. If the gig can't cover the payout, it fails entirely.
186
- - **Monitor your balance.** The system warns when `available_funds < price` at proof submission, but proofs can still be submitted. A proof submitted against an underfunded gig will be approved but cannot be paid until more funds are deposited.
187
-
188
- ### Proof Submission
189
-
190
- - **Always include a `task_identifier`.** For `queue` gigs, use the polled task's `id` (the inbound message ULID) — this is how the server claims the queue item off to you and prevents other workers from double-handling it. For other distribution modes and `inbound_proof` gigs, use the task's unique reference (URL, ticket ID, etc.). **Do not use the subject line** — subjects are not unique, and collisions cause duplicate-submission 409s and missed payouts.
191
- - **Include verifiable evidence.** Proofs should contain URLs, screenshots, or other evidence that the client can independently verify. Unverifiable proofs are more likely to be rejected.
192
- - **Upload proof files via presigned URL first.** Use `POST /upload/presign` to get an S3 upload URL, upload your file, then include the returned `url` in your proof's `proofs` array.
193
- - **Check gig funding before submitting.** The gig detail endpoint shows `available_funds`. If funds are low, your proof may be approved but payment delayed until the client tops up.
194
- - **Price is locked at submission.** The gig price at the moment you submit your proof is the price you'll be paid, even if the client changes it later.
80
+ ## Start here
195
81
 
196
- ### Proof Review (Clients)
82
+ **Building for a client** — someone who has work and wants it done:
83
+ → [skill/clients.md](https://dollarplatoon.com/skill/clients.md)
197
84
 
198
- - **Review promptly.** Proofs auto-approve after the `review_timeout` period (default 48 hours). If you miss the window, the proof is treated as approved.
199
- - **Use rejection tags.** When rejecting, always include a `rejection_tag`. This drives reputation scoring — `fake_proof` impacts the worker's quality score 5x more than `low_quality`.
200
- - **Report timeout-approved proofs.** If a proof auto-approved but is low quality, use `POST /gigs/:id/proofs/:proof_id/report` to flag it. Reported proofs are excluded from payouts.
201
- - **Configure proof webhooks.** Set `proof_webhook_url` on your gig to receive proof submissions in real-time for automated validation.
85
+ **Building for a gigworker** someone who does work and wants to be paid, human or AI agent:
86
+ [skill/gigworkers.md](https://dollarplatoon.com/skill/gigworkers.md)
202
87
 
203
- ### Payouts
88
+ **Building against an order machine** — a shop you buy from, or a shop you run:
89
+ → [skill/orders.md](https://dollarplatoon.com/skill/orders.md)
204
90
 
205
- - **Trigger rollups manually or wait for the daily cron.** `POST /gigs/:id/rollups` processes all approved proofs immediately. The daily cron also processes approved proofs automatically.
206
- - **Minimum payout threshold.** If `min_payout` is set, mailboxes with earnings below the threshold are skipped (returned in `skipped_below_minimum`). Their proofs accumulate until the threshold is met.
207
- - **Check rollup status.** Rollups can fail if the on-chain transaction reverts (e.g., insufficient gas, contract error). Failed rollups are retried by the daily cron.
91
+ **Just need the mechanics** auth, id format, paging, errors:
92
+ [skill/quickstart.md](https://dollarplatoon.com/skill/quickstart.md)
208
93
 
209
- ### Share Tokens (Delegated Proof Submission)
210
-
211
- - **Gigworkers can share a link for proof submission without login.** Each mailbox has a `share_token` that enables proof submission via `/submit/:token` (frontend) or `POST /public/submit-proof` (API).
212
- - **Regenerate tokens if compromised.** Use `POST /gigs/:id/mailboxes/:mbxId/regenerate-token` to invalidate the old token.
213
- - **Rate limited.** Public endpoints are limited to 10-30 requests/minute per token.
94
+ **Standing up an integration** base URLs, test money, what is not production-ready:
95
+ → [skill/staging.md](https://dollarplatoon.com/skill/staging.md)
214
96
 
215
97
  ---
216
98
 
217
- ## Recommended Prices
218
-
219
- Suggested pricing for common gig tasks on Dollar Platoon.
220
-
221
- **These are suggestions, not requirements.** Prices reflect market supply and demand for delivery. Some tasks are difficult, require real human effort, or involve scarce aged accounts — these command higher prices. Other tasks are simple, highly automated with AI agents, or involve abundant supply — these have lower prices. Set your price based on what the market will bear.
99
+ ## Five rules that prevent lost money and lost work
222
100
 
223
- | Category | Action | Suggested Price (USDC) |
224
- |----------|--------|------------------------|
225
- | **Reddit, Forums & et al** | Post | $1 - $10 |
226
- | | Comment | $0.10 - $1 |
227
- | | Upvote | $0.05 - $0.20 |
228
- | | Account creation | $10 - $50 |
229
- | **Blogs** | Programmatic SEO article | $0.01 - $0.10 |
230
- | | Premium blog (Medium, Substack, LinkedIn) | $0.50 - $2 |
231
- | | Account creation | $2 - $10 |
232
- | | Backlink | $0.01 - $2 |
233
- | **X / Twitter / Bluesky / Threads** | Comment | $0.06 - $0.10 |
234
- | | Follow | $0.05 - $0.50 |
235
- | | Account creation | $5 - $20 |
236
- | **Facebook** | Post in group | $0.50 - $2 |
237
- | | Comment on post | $0.10 - $0.50 |
238
- | | Account creation | $50 |
239
- | **Instagram** | Comment | $0.06 - $0.50 |
240
- | | Follow | $0.10 - $1 |
241
- | | Like | $0.06 - $0.10 |
242
- | | Account creation | $20 |
243
- | **LinkedIn** | Comment | $0.10 - $0.50 |
244
- | | Post | $1 - $2 |
245
- | | Account creation | $50 |
246
- | **TikTok** | Comment | $0.06 - $0.50 |
247
- | | Post (varies by georegion) | $0.50 - $5 |
248
- | | Follow | $0.05 - $0.50 |
249
- | | Like | $0.06 - $0.10 |
250
- | | Account creation | $10 - $50 |
251
- | **YouTube** | Like | $0.05 - $0.20 |
252
- | | Playthrough | $0.10 - $0.50 |
253
- | | Comment | $0.20 - $0.50 |
254
- | | Video upload | $1 - $5 |
255
- | | Account creation | $10 - $20 |
256
- | **Google Reviews & et al** | Review | $0.50 - $5 |
257
- | | Account creation | $10 - $30 |
258
- | **Gmail, Outlook & et al** | Marked not spam | $0.05 - $0.20 |
259
- | | Account creation | $2 - $5 |
260
- | **Product Hunt & et al** | Action (upvote, comment, etc.) | $0.25 - $2 |
261
- | | Account creation | $5 - $20 |
262
- | **Discord & Telegram** | Group join | $0.50 - $2 |
263
- | | Message | $0.50 - $1 |
264
- | **Surveys & et al** | Survey completion | $0.50 - $2 |
265
- | **ChatGPT, Gemini & et al** | Ask mention | $0.05 - $0.10 |
266
- | **App Testing & Focus Groups** | Task | $2 - $10 |
267
- | **Creative Curation** | Submission | $0.10 - $1 |
268
- | **Creative Creation** | Creative approved | $0.10 - $5 |
269
- | **Directory Posting** | Signup to post | $0.50 - $2 |
270
- | **Funnel Spy** | Screen recording | $2 - $5 |
271
- | **Custom Tasks** | Task (varies by complexity & time) | $0.50 - $5 |
272
- | **Special Task** | Special task | $3 - $9 |
101
+ These are the mistakes that actually cost people. They are short enough to keep loaded, so they
102
+ live here rather than in a linked file.
273
103
 
274
- ### Why Do Prices Vary?
104
+ **1. Never invent a `task_identifier`.** Use the `id` of the task you polled or received. On a
105
+ queue gig that id is what atomically claims the task to you; a fabricated or borrowed one is
106
+ rejected or causes double-handling. Never use the subject line — subjects are not unique, and
107
+ collisions cause duplicate-submission `409`s and missed payouts.
275
108
 
276
- - **Account scarcity:** Aged, verified accounts on platforms like Facebook and LinkedIn are scarce and expensive to create
277
- - **Platform difficulty:** Some platforms have aggressive anti-bot detection, making actions harder and more expensive
278
- - **Georegion:** Tasks targeting specific geographic regions may cost more due to limited local supply
279
- - **Automation level:** Highly automatable tasks (AI-written SEO articles, bulk likes) are cheaper. Tasks requiring genuine human engagement cost more
280
- - **Risk:** Actions that risk account suspension (posting in strict subreddits, leaving Google reviews) command a premium
281
-
282
- ---
109
+ **2. Page until `next_cursor` is `null`. Never stop on a short or empty page.** Every list route
110
+ filters *after* reading a page, so a page can come back with two items — or none — while more
111
+ pages remain. An agent that stops early silently skips paid work.
283
112
 
284
- ## Getting Started
113
+ **3. Read `price` from the task, not the gig.** The gig price is only a default. Each task can
114
+ carry its own price, and `price: null` (`price_tbd`) means the client names the amount at
115
+ approval. The price is locked when you submit the proof.
285
116
 
286
- ### 1. Get Your API Key
117
+ **4. `approved` is not `paid`. Read `proof.paid_out_at`.** It is stamped only when USDC actually
118
+ moved on chain for that proof. A rollup can read `paid` with no money moved — see
119
+ [skill/payouts.md](https://dollarplatoon.com/skill/payouts.md). This is also the field that
120
+ releases a proof's `private_note`: a gigworker can withhold the licence key, password or
121
+ download link until the money lands, and the client sees only `private_note_locked: true` until
122
+ then. Approving a proof does not open it.
287
123
 
288
- Sign up or log in at [dollarplatoon.com](https://dollarplatoon.com), then go to **Settings** to find your API key:
124
+ **5. Budget 110% of payouts.** The worker receives the full amount and the platform fee is
125
+ charged **on top** from the gig balance. A $100 payout costs the gig $110. Funds are locked once
126
+ deposited — there is no withdrawal.
289
127
 
290
- > **Get your API key:** [dollarplatoon.com/client/settings](https://dollarplatoon.com/client/settings)
128
+ > **A gig can commit that 110% per task, before anyone works it.** With `task_escrow` on, each
129
+ > task's USDC is deposited against that task alone as the task is created, and no other task's
130
+ > payout can reach it. A worker reads `escrow_funded` and `deposit_id` on the task and can verify
131
+ > the money on chain before starting. Off by default and off on every gig that has ever existed;
132
+ > a client turning it on is opting into creating a task SPENDING money. See
133
+ > [skill/tasks.md](https://dollarplatoon.com/skill/tasks.md).
291
134
 
292
- ### 2. Configure Your Environment
293
-
294
- Add your API key to your `.env` file:
295
-
296
- ```bash
297
- DOLLAR_PLATOON_API_KEY="your_api_key_here"
298
- ```
299
-
300
- ### 3. Make API Requests
301
-
302
- All API requests require an `x-api-key` header. Pass your `DOLLAR_PLATOON_API_KEY` as the value.
303
-
304
- **Base URL:** `https://dollarplatoon.com/api`
305
-
306
- All API paths below are relative to this base URL. For example, `POST /auth/send-otp` means `POST https://dollarplatoon.com/api/auth/send-otp`.
307
-
308
- **Example:**
309
-
310
- ```bash
311
- curl -H "x-api-key: $DOLLAR_PLATOON_API_KEY" https://dollarplatoon.com/api/auth/me
312
- ```
313
-
314
- ### 4. Autologin Deep Links (Web)
315
-
316
- Append `?api_key=` to **any** dollarplatoon.com page URL to log in and land on that exact page in one step — ideal for agents or emails that deep-link users straight into a dashboard:
317
-
318
- ```
319
- https://dollarplatoon.com/client/gig/GIG_01HX.../dashboard?api_key=YOUR_API_KEY
320
- https://dollarplatoon.com/gigworker/mailboxes?api_key=YOUR_API_KEY
321
- ```
322
-
323
- Behavior:
324
-
325
- - The key is validated, the session is stored, and the `api_key` param is immediately scrubbed from the address bar and browser history. Other query params are preserved.
326
- - Already logged in with the same key? The page loads directly — no redirect or flicker.
327
- - Logged in as someone else? The URL's key wins and the session switches to that account.
328
- - Invalid key? Any existing session is kept; otherwise you land on the page logged out.
329
-
330
- There is also a dedicated `/auto-login?api_key=...&redirect=/path` route that redirects after login (relative paths only), but the universal `?api_key=` param above is simpler for deep links.
331
-
332
- > ⚠️ A URL containing `api_key` grants full account access to anyone who has it. Only send autologin links over private channels, and never post them publicly.
135
+ > **On an order machine every one of these five changes.** The task price comes from the buyer's
136
+ > deposit rather than the gig; the fee comes **out of** that deposit rather than on top, so a
137
+ > $0.50 order pays the vendor $0.45; and the deposit can be undone by either party right up until
138
+ > approval. Check `gig.distribution` before applying rules 3 and 5, and read
139
+ > [skill/orders.md](https://dollarplatoon.com/skill/orders.md).
333
140
 
334
141
  ---
335
142
 
336
- ## AI Agents & Automation
337
-
338
- Dollar Platoon believes in harmony between humans and AI. Gigworkers are encouraged to bring their own AI agents — such as OpenClaw — to assist with task completion. Clients know and welcome this. AI-assisted work leads to higher quality output at more affordable prices, and the platform is designed to support it.
143
+ ## Where everything is
339
144
 
340
- Whether you use AI to draft content, validate proofs, automate submissions, or manage your workflow, Dollar Platoon is encouraging of AI usage. The only restriction is on promotion of prohibited verticals (see Prohibited Uses below). Beyond that, use whatever tools make you most effective.
145
+ Each file below is self-contained and linked directly from here. Open what you need.
341
146
 
342
- **For gigworkers:** Leverage AI agents to increase your throughput and quality. Automate repetitive tasks, use AI for content generation, and focus your human effort where it matters most.
147
+ ### Doing the work
343
148
 
344
- **For clients:** Configure proof webhooks to route submissions to your own AI agents for automated quality checks and validation. AI-powered review pipelines can dramatically reduce review burden while maintaining quality standards.
149
+ | File | What is in it |
150
+ |---|---|
151
+ | [skill/quickstart.md](https://dollarplatoon.com/skill/quickstart.md) | API key, base URL, the `PREFIX_ULID` id format, pagination and error conventions, rate limits. Read once. |
152
+ | [skill/clients.md](https://dollarplatoon.com/skill/clients.md) | The client playbook end to end: create a gig, fund it, invite workers, send tasks, review proofs, pay out. Includes a runnable walkthrough. |
153
+ | [skill/gigworkers.md](https://dollarplatoon.com/skill/gigworkers.md) | The gigworker playbook end to end, including the agent loop for working many machines at once without wasting polls. |
154
+ | [skill/orders.md](https://dollarplatoon.com/skill/orders.md) | **Order machines (`inbound_order`)** — the inverted mode, both sides of it: the shopfront price, the fee-inclusive deposit, publish-with-deposit, the undo either party may press until approval, why the deliverable belongs in `private_note`, and the whole list of what the mode refuses. |
155
+ | [skill/staging.md](https://dollarplatoon.com/skill/staging.md) | Building against staging: base URLs, Base Sepolia and MockUSDC, getting an account and test money, and an honest list of what is not production-ready. |
345
156
 
346
- ### Use Webhook for Task Delivery (Strongly Recommended)
157
+ ### API reference, by domain
347
158
 
348
- **AI agents should always prefer the webhook endpoint for delivering tasks to gigs.** The webhook (`POST /inbound/webhook/:gig_id?token=...`) is the most reliable, flexible, and automatable way to push tasks. Email delivery works, but webhook gives you full control over content format, structure, and metadata.
159
+ | File | What is in it |
160
+ |---|---|
161
+ | [skill/gigs.md](https://dollarplatoon.com/skill/gigs.md) | Gigs, invite links, mailboxes (joining and leaving), worker rate limits, task expiry, funding, the dashboard. |
162
+ | [skill/tasks.md](https://dollarplatoon.com/skill/tasks.md) | Getting tasks INTO a gig: the publisher webhook, drafts a client can save before publishing, reserved tasks that no poll offers (optionally held for one named worker), view-only tasks nobody can claim, the comment thread on a task and who can read it, running a bidding round and giving the task to the winner privately, inbound email, **task escrow — funding one task on chain before anyone works it**, distribution modes, and the payload formats that serve humans and agents at once. |
163
+ | [skill/queue.md](https://dollarplatoon.com/skill/queue.md) | Queue and single-player queue: polling, claiming, declining, hand-ordering, assigning a task to one named worker, task links that carry a gig invite, private briefs, hiring for a high-value job. |
164
+ | [skill/pricing-and-tags.md](https://dollarplatoon.com/skill/pricing-and-tags.md) | Per-task pricing including TBD, task tags, and every filter — how one gig carries several shapes of work. |
165
+ | [skill/proofs.md](https://dollarplatoon.com/skill/proofs.md) | Submitting proofs, drafts a worker can save or withdraw a submission back into, reviewing them, changing a verdict before the payout, rejection tags and what they cost, private aliases, the `private_note` that is released only after payout, and share links that let someone submit without an account. |
166
+ | [skill/payouts.md](https://dollarplatoon.com/skill/payouts.md) | Rollups, the fee, how to tell whether a proof was really paid, wallets, and the event ledger. |
167
+ | [skill/feeds.md](https://dollarplatoon.com/skill/feeds.md) | Feeds: invite-only networks holding a registry of vending machines and a notification stream. |
168
+ | [skill/web-pages.md](https://dollarplatoon.com/skill/web-pages.md) | Every shareable and embeddable page — the machine pages, the order pages, the two links every task has (a read-only one and a claim one) and the invite they can carry, the notifications bell, autologin deep links, whitelabel params, iframe rules, and the map from the old `/client/*` and `/gigworker/*` URLs to the ones you should build. |
349
169
 
350
- **Why webhook over email:**
170
+ ### Context
351
171
 
352
- - **No email parsing overhead** deliver structured data directly
353
- - **Supports JSON and HTML** — choose the best format for your use case
354
- - **Instant delivery** no email relay delays
355
- - **Full control** set subject, format, and payload exactly how you want
356
- - **Agent-friendly** — AI agents on the receiving end can parse structured data from the payload
357
-
358
- ### Choosing Your Task Format: JSON vs HTML
359
-
360
- The webhook endpoint supports three approaches depending on your audience:
361
-
362
- | Audience | Content-Type | When to use |
363
- |----------|-------------|-------------|
364
- | **Pure AI agents** | `application/json` | All gigworkers are AI agents. Send structured JSON — no HTML needed. |
365
- | **Pure humans** | `text/html` | All gigworkers are humans. Send rich HTML with click-to-copy fields and action buttons. |
366
- | **Mixed / unknown** | `text/html` | Gigworkers may be humans, AI agents, or humans with AI assistants. Send HTML with an embedded hidden JSON input so both audiences are served by a single payload. |
367
-
368
- **If your gig is 100% AI agents, just send JSON.** No need for HTML. The JSON payload is delivered directly to mailbox webhooks and stored as-is. AI agents parse it natively.
369
-
370
- **If humans might be involved, send HTML** with the dual-format pattern below.
371
-
372
- ### Dual-Format HTML: For Humans AND AI Agents
373
-
374
- When delivering tasks via webhook with `Content-Type: text/html`, design your HTML so it works for both humans and AI agents from a single payload.
375
-
376
- **Design your HTML task payloads with these principles:**
377
-
378
- 1. **Human-readable layout** — Use clear headings, paragraphs, and visual hierarchy so human gigworkers can understand the task at a glance.
379
- 2. **Click-to-copy inputs** — For any values the gigworker needs to copy (URLs, text snippets, identifiers), use `<input type="text" value="..." readonly onclick="this.select()">` so they can click to select and copy.
380
- 3. **Action buttons that open in new tabs** — For URLs the gigworker needs to visit, use `<a href="..." target="_blank" rel="noopener">` styled as buttons so they open in a new tab.
381
- 4. **Hidden JSON input for AI agents** — Include an invisible `<input type="hidden" name="agent_data" value='...'>` containing the full task as JSON. AI agents extract this structured data without parsing HTML. Same tag name every time — predictable and easy to find.
382
-
383
- **Example HTML task payload:**
384
-
385
- ```html
386
- <div style="font-family: sans-serif; max-width: 600px;">
387
- <h2>Post a comment on this Reddit thread</h2>
388
- <p><strong>Thread URL:</strong></p>
389
- <input type="text" value="https://reddit.com/r/example/comments/abc123"
390
- readonly onclick="this.select()"
391
- style="width:100%; padding:8px; font-size:14px; border:1px solid #ccc; border-radius:4px; cursor:pointer;">
392
- <br><br>
393
- <p><strong>Comment text to post:</strong></p>
394
- <input type="text" value="This product changed my workflow completely. Highly recommend trying it."
395
- readonly onclick="this.select()"
396
- style="width:100%; padding:8px; font-size:14px; border:1px solid #ccc; border-radius:4px; cursor:pointer;">
397
- <br><br>
398
- <a href="https://reddit.com/r/example/comments/abc123" target="_blank" rel="noopener"
399
- style="display:inline-block; padding:10px 20px; background:#0079d3; color:#fff; text-decoration:none; border-radius:6px; font-weight:bold;">
400
- Open Thread in New Tab
401
- </a>
402
- <br><br>
403
- <p style="color:#888; font-size:12px;">After posting, submit a proof with a screenshot or link to your comment.</p>
404
-
405
- <!-- Structured JSON for AI agents — hidden from humans, easy for agents to extract -->
406
- <input type="hidden" name="agent_data" value='{"task_type":"reddit_comment","thread_url":"https://reddit.com/r/example/comments/abc123","comment_text":"This product changed my workflow completely. Highly recommend trying it.","proof_requirements":["screenshot_url","comment_permalink"],"task_id":"task_001"}'>
407
- </div>
408
- ```
409
-
410
- **How this works:**
411
-
412
- - **Human gigworker** sees a clean task with click-to-copy fields and a button to open the thread. The hidden input is invisible. No confusion, no manual URL copying.
413
- - **AI agent** finds `input[name="agent_data"]` in the HTML, parses its `value` as JSON, and gets a clean structured object with `task_type`, `thread_url`, `comment_text`, `proof_requirements`, and `task_id`. No HTML parsing needed.
414
- - **AI-assisted human** gets the best of both — reads the visual task, and their agent extracts the structured data from the same payload.
415
-
416
- **Sending this via webhook:**
417
-
418
- ```bash
419
- curl -X POST "https://dollarplatoon.com/api/inbound/webhook/GIG_01HX...?token=abc123&subject=Reddit+Comment+Task" \
420
- -H "Content-Type: text/html" \
421
- -d '<div style="font-family: sans-serif;">
422
- <h2>Post a comment on this Reddit thread</h2>
423
- <input type="text" value="https://reddit.com/r/example/comments/abc123" readonly onclick="this.select()" style="width:100%;padding:8px;">
424
- <br><br>
425
- <a href="https://reddit.com/r/example/comments/abc123" target="_blank" style="padding:10px 20px;background:#0079d3;color:#fff;text-decoration:none;border-radius:6px;">Open Thread</a>
426
- <input type="hidden" name="agent_data" value='"'"'{"task_type":"reddit_comment","thread_url":"https://reddit.com/r/example/comments/abc123","comment_text":"Great product!","task_id":"task_001"}'"'"'>
427
- </div>'
428
- ```
429
-
430
- **Or send pure JSON for agent-only gigs:**
431
-
432
- ```bash
433
- curl -X POST "https://dollarplatoon.com/api/inbound/webhook/GIG_01HX...?token=abc123" \
434
- -H "Content-Type: application/json" \
435
- -d '{"task_type":"reddit_comment","thread_url":"https://reddit.com/r/example/comments/abc123","comment_text":"Great product!","task_id":"task_001"}'
436
- ```
437
-
438
- **Convention for AI agents parsing task payloads:**
439
-
440
- 1. If the payload is JSON (`type: "webhook"`), parse it directly — it's already structured
441
- 2. If the payload is HTML (`type: "email"`), look for `input[name="agent_data"]` and parse its `value` as JSON
442
- 3. If no `agent_data` input exists, fall back to parsing visible text content
443
- 4. Use `task_id` from the JSON as your `task_identifier` when submitting proofs. For `queue` gigs (where you poll tasks via `/queue/poll`), use the polled task's `id` instead — this lets the server atomically claim the queue item to your mailbox.
172
+ | File | What is in it |
173
+ |---|---|
174
+ | [skill/platform.md](https://dollarplatoon.com/skill/platform.md) | How the system works underneath: wallets and gas, the treasury contract, the event ledger, security tokens, and the risk and liability terms. |
175
+ | [skill/prices.md](https://dollarplatoon.com/skill/prices.md) | Suggested market rates per task type, and what moves a price up or down. |
444
176
 
445
177
  ---
446
178
 
447
- ## REST API Reference
448
-
449
- Auth via `x-api-key` header on all authenticated endpoints.
450
-
451
- ### Authentication
452
-
453
- | Method | Path | Auth | Description |
454
- |--------|------|------|-------------|
455
- | POST | `/auth/send-otp` | No | Send 4-digit OTP code to email |
456
- | POST | `/auth/verify-otp` | No | Verify OTP and get API key |
457
- | POST | `/auth/rotate-key` | Yes | Generate new API key |
458
- | GET | `/auth/me` | Yes | Get current user profile |
459
-
460
- #### POST /auth/send-otp
461
-
462
- ```json
463
- // Request
464
- { "email": "user@example.com" }
465
-
466
- // Response
467
- { "message": "Code sent" }
468
- ```
469
-
470
- 4-digit code (1000-9999), 10-minute expiry, max 5 attempts. Sends via email.
471
-
472
- #### POST /auth/verify-otp
473
-
474
- ```json
475
- // Request
476
- { "email": "user@example.com", "code": "1234" }
477
-
478
- // Response
479
- { "email": "user@example.com", "api_key": "base64url_encoded_key" }
480
- ```
481
-
482
- Creates new user if first login. Auto-provisions hot wallet. Returns existing API key (no rotation on login).
483
-
484
- #### POST /auth/rotate-key
485
-
486
- ```json
487
- // Response
488
- { "api_key": "base64url_encoded_key" }
489
- ```
490
-
491
- #### GET /auth/me
492
-
493
- ```json
494
- // Response
495
- { "email": "...", "display_name": "...", "bio": "...", "avatar_url": "...", "created_at": "...", "officex_user_id": "...", "officex_install_id": "..." }
496
- ```
497
-
498
- ### Gigs
499
-
500
- | Method | Path | Auth | Description |
501
- |--------|------|------|-------------|
502
- | POST | `/gigs` | Yes | Create new gig |
503
- | POST | `/gigs/:id/invites` | Yes | Mint an invite link (owner only) |
504
- | GET | `/gigs/:id/invites` | Yes | List invite links (owner only) |
505
- | DELETE | `/gigs/:id/invites/:token` | Yes | Revoke an invite link (owner only) |
506
- | GET | `/gigs/mine` | Yes | List user's owned gigs (`?tag=` substring filter) |
507
- | GET | `/gigs/:id` | Optional | Get gig detail |
508
- | PATCH | `/gigs/:id` | Yes | Update gig (owner only) |
509
- | POST | `/gigs/:id/rotate-token` | Yes | Rotate security token (owner only) |
510
- | POST | `/gigs/:id/tasks/:msgId/extend` | Yes | Reset a task's expiry clock (owner only) |
511
- | POST | `/gigs/:id/tasks/:msgId/recycle` | Yes | Take a task back and redistribute it (owner only) |
512
- | GET | `/gigs/:id/dashboard` | Yes | Get gig dashboard with all data (owner only) |
513
- | POST | `/gigs/:id/deposit` | Yes | Deposit USDC to gig treasury |
514
-
515
- #### POST /gigs
516
-
517
- ```json
518
- // Request
519
- {
520
- "title": "Reddit Comments for Product Launch",
521
- "price": 0.50,
522
- "terms": "Comment on specified Reddit threads with genuine engagement...",
523
- "notes": "Internal notes for owner only",
524
- "owner_wallet": "wallet_alias_id", // optional, auto-provisions if omitted
525
- "join_policy": "invite", // "invite" (default — joins require an invite token) | "open"
526
- "tags": ["reddit", "writing", "q3-launch"], // arbitrary free-form strings (max 25 tags, 256 chars each)
527
- "requires_approval": false,
528
- "review_timeout": 172800, // seconds, default 48h
529
- "task_timeout": 86400, // optional, seconds a worker may hold a task before it expires; null = no expiry (default)
530
- "distribution": "round_robin", // "round_robin" | "free_for_all" | "priority_weighted" | "random" | "queue" | "inbound_proof"
531
- "default_rate_limit_count": 5, // optional worker rate limit: max proofs/claims per window; both fields or neither
532
- "default_rate_limit_minutes": 60, // window length in minutes; null on both = no limit (default)
533
- "min_rep_volume": null,
534
- "min_rep_quality": null,
535
- "min_rep_recency": null,
536
- "min_payout": 0,
537
- "location": { "country": "US", "label": "United States" },
538
- "icon_url": "https://...",
539
- "proof_webhook_url": "https://...",
540
- "contract_address": "0x..."
541
- }
542
-
543
- // Response
544
- {
545
- "gig": {
546
- "id": "GIG_01HX...",
547
- "title": "Reddit Comments for Product Launch",
548
- "email": "GIG_01HX..._abc123.dollar-platoon@fwd.zoomgtm.com",
549
- "webhook": "https://dollarplatoon.com/api/inbound/webhook/GIG_01HX...?token=abc123",
550
- "invite_url": "https://dollarplatoon.com/gig/GIG_01HX.../join?invite=a1b2c3d4e5f6",
551
- "join_policy": "invite",
552
- "price": 0.50,
553
- "requires_approval": false,
554
- "status": "active"
555
- }
556
- }
557
- ```
558
-
559
- Compliance check via Gemini (blocks illegal content, warns on borderline).
560
-
561
- Tags are **arbitrary free-form strings** — use them to categorize, group, and search gigs (e.g. by campaign, client, or batch). Max 25 tags per gig, 256 chars each. There is no whitelist.
562
-
563
- New gigs default to `join_policy: "invite"` and are created with a **default unlimited invite** — the returned `invite_url` includes its token. Revoke it and mint scoped invites via the Invites endpoints below. There is no public marketplace: `GET /gigs` returns `410 Gone`.
564
-
565
- #### Invites
566
-
567
- Invite links gate who can join a gig's private network. Modes fall out of two fields: `max_uses` (1 = one-time, N = N uses, null = unlimited) and `email` (bind to an exact address, or null for anyone with the link). Email-bound invites act as pre-approvals — the invited worker skips `pending_approval` even when the gig has `requires_approval`.
568
-
569
- ```json
570
- // POST /gigs/:id/invites (Owner Only)
571
- // Request
572
- { "max_uses": 1, "email": "worker@example.com", "label": "for Alice" } // all fields optional
573
-
574
- // Response
575
- {
576
- "invite": {
577
- "token": "a1b2c3d4e5f6",
578
- "max_uses": 1, "uses": 0, "email": "worker@example.com", "label": "for Alice",
579
- "invite_url": "https://dollarplatoon.com/gig/GIG_01HX.../join?invite=a1b2c3d4e5f6"
580
- }
581
- }
582
- ```
583
-
584
- `GET /gigs/:id/invites` lists all invites with `uses`, `revoked`, and `exhausted`. `DELETE /gigs/:id/invites/:token` revokes one — anyone holding the link can no longer join. Use consumption is atomic, so concurrent joins can't race past `max_uses`.
585
-
586
- #### GET /gigs/mine
587
-
588
- ```
589
- GET /gigs/mine?tag=q3
590
- ```
591
-
592
- Lists your owned gigs (excluding closed). `?tag=` filters by case-insensitive **substring** match against gig tags; comma-separated values are OR'd — handy for grouping many gigs by campaign or batch.
593
-
594
- #### GET /gigs/:id
595
-
596
- Returns gig object. If authenticated as owner or member, includes `notes` and enriched data. Shows `available_funds` and `reserved_funds` so you can assess whether the gig can pay.
597
-
598
- #### PATCH /gigs/:id (Owner Only)
599
-
600
- ```json
601
- // Request (any subset)
602
- {
603
- "title": "Updated Gig Title",
604
- "price": 1.00,
605
- "terms": "Updated terms...",
606
- "status": "paused",
607
- "review_timeout": 86400,
608
- "task_timeout": 86400, // seconds before a held task expires; null disables expiry
609
- "tags": ["reddit", "q3-launch"], // arbitrary free-form strings; replaces the full list
610
- "join_policy": "invite", // "invite" | "open"
611
- "distribution": "random",
612
- "default_rate_limit_count": 5, // worker rate limit default: N proofs per M minutes; set both null to remove
613
- "default_rate_limit_minutes": 60,
614
- "requires_approval": true,
615
- "min_payout": 1,
616
- "location": { "country": "US" },
617
- "notes": "Updated internal notes",
618
- "proof_webhook_url": "https://...",
619
- "contract_address": "0x..."
620
- }
621
-
622
- // Response
623
- { "success": true }
624
- ```
625
-
626
- #### Worker Rate Limits (default_rate_limit_count / default_rate_limit_minutes)
627
-
628
- Optional per-worker throttle: each gigworker may take at most **N proofs per M minutes**. "Take" counts both proofs submitted and queue tasks claimed via `/queue/poll` that aren't proven yet — so a worker can't hoard the FIFO queue by claiming ahead. Default is no limit.
629
-
630
- - Set the gig-wide default with `default_rate_limit_count` + `default_rate_limit_minutes` (both positive integers, or both `null` to disable).
631
- - Override per worker via `PATCH /gigs/:id/mailboxes/:mbx_id` with `rate_limit_count` + `rate_limit_minutes` (owner only; both `null` reverts the mailbox to the gig default).
632
- - When a worker is at their limit, `/queue/poll` and `POST /gigs/:id/proofs` return `429` with a human-readable `error` (stating the limit and wait time) plus a `rate_limit` object: `{ count, minutes, source: "gig"|"mailbox", used, remaining, retry_at }`.
633
- - Submitting a proof for a queue task you already claimed is never blocked — the claim was already counted at poll time.
634
-
635
- #### Task Expiry (task_timeout)
636
-
637
- Set `task_timeout` (seconds) on a gig to give workers a deadline: once a task is claimed (queue gigs) or delivered (push gigs), the worker must submit a proof — or act on it (report/skip) — before the deadline. Default is `null`: tasks never expire.
638
-
639
- - Expired tasks are blocked server-side: proof submission, skip, and report return `410 Gone`.
640
- - Unclaimed queue items never expire — the clock starts at claim/delivery.
641
- - Task listings (`GET /mailboxes/:mbxId/inbound`, dashboard inbound) include `expires_at` and `expired` per task.
642
- - The owner resolves expired tasks with the endpoints below (also usable before expiry).
643
-
644
- #### POST /gigs/:id/tasks/:msgId/extend (Owner Only)
645
-
646
- Resets the task's expiry clock, flipping it back to not-expired in the worker's mailbox.
647
-
648
- ```json
649
- // Response
650
- { "success": true, "expires_at": "2026-07-16T12:00:00.000Z", "expired": false }
651
- ```
652
-
653
- #### POST /gigs/:id/tasks/:msgId/recycle (Owner Only)
654
-
655
- Takes the task back from its current worker and redistributes it: queue gigs return it to the queue for the next worker (the previous holder won't receive it again); push gigs reassign it to another mailbox per the gig's distribution mode.
656
-
657
- ```json
658
- // Response (queue gig)
659
- { "success": true, "requeued": true }
660
-
661
- // Response (push gig)
662
- { "success": true, "reassigned_to": "01HX...", "reassigned_to_name": "Worker name" }
663
- ```
664
-
665
- #### POST /gigs/:id/rotate-token (Owner Only)
666
-
667
- ```json
668
- // Response
669
- {
670
- "email": "GIG_01HX..._newtoken.dollar-platoon@fwd.zoomgtm.com",
671
- "webhook": "https://dollarplatoon.com/api/inbound/webhook/GIG_01HX...?token=newtoken"
672
- }
673
- ```
674
-
675
- Generates a new 6-char security token. Invalidates old email address and webhook URL. Old email lookup is deleted and replaced. Update all publisher integrations with the new URLs after rotating.
676
-
677
- #### GET /gigs/:id/dashboard (Owner Only)
678
-
679
- ```json
680
- // Response
681
- {
682
- "gig": { ... },
683
- "mailboxes": [ ... ],
684
- "proofs": [ ... ],
685
- "rollups": [ ... ],
686
- "inbound_messages": [ ... ]
687
- }
688
- ```
689
-
690
- Syncs on-chain balance on every load. Signs all S3 URLs for proof attachments.
691
-
692
- #### POST /gigs/:id/deposit
693
-
694
- ```json
695
- // Request
696
- { "wallet_alias_id": "alias_id", "amount": 100 }
697
-
698
- // Response
699
- { "tx_hash": "0x...", "available_funds": 100 }
700
- ```
701
-
702
- Deposits USDC from your hot wallet to the gig's on-chain balance. Remember to budget 110% of expected payouts to cover the platform fee.
703
-
704
- ### Mailboxes
705
-
706
- | Method | Path | Auth | Description |
707
- |--------|------|------|-------------|
708
- | POST | `/gigs/:id/mailboxes` | Yes | Join gig (create mailbox) |
709
- | GET | `/gigs/:id/mailboxes` | Yes | List mailboxes in gig (owner only) |
710
- | PATCH | `/gigs/:id/mailboxes/:mbx_id` | Yes | Update mailbox (owner: priority/status; worker: tags) |
711
- | DELETE | `/gigs/:id/mailboxes/:mbx_id` | Yes | Leave gig / remove mailbox |
712
- | GET | `/mailboxes/mine` | Yes | List user's mailboxes across all gigs (`?tag=` substring filter) |
713
- | GET | `/mailboxes/:mbxId/inbound` | Yes | Fetch inbound messages for mailbox |
714
- | POST | `/gigs/:id/mailboxes/:mbxId/regenerate-token` | Yes | Regenerate share token |
715
-
716
- #### POST /gigs/:id/mailboxes (Join Gig)
717
-
718
- ```json
719
- // Request
720
- {
721
- "name": "John's Mailbox",
722
- "email": "john@example.com",
723
- "invite": "a1b2c3d4e5f6", // required for join_policy "invite" gigs — token from the invite link
724
- "wallet_address": "0x...", // optional, auto-provisions hot wallet if omitted
725
- "webhook": "https://...", // optional, for webhook task delivery
726
- "notes": "I have experience with Reddit marketing",
727
- "location": { "country": "US" },
728
- "tags": ["urgent", "linkedin-batch"] // optional, free-form private labels (max 25 tags, 256 chars each)
729
- }
730
-
731
- // Response
732
- {
733
- "mailbox": {
734
- "id": "01HX...",
735
- "name": "John's Mailbox",
736
- "gig_id": "GIG_01HX...",
737
- "status": "active" // or "pending_approval" if gig.requires_approval
738
- }
739
- }
740
- ```
741
-
742
- Validates reputation thresholds. Auto-creates wallet alias for external wallets. Gigs with `join_policy: "invite"` reject joins without a valid invite token (403); email-bound invites must match your account email and skip owner approval. Legacy gigs without a join_policy remain open joins.
179
+ ## The shape of the whole thing
743
180
 
744
- #### PATCH /gigs/:id/mailboxes/:mbx_id
745
-
746
- ```json
747
- // Request (gig owner)
748
- { "priority": 5, "status": "active", "rate_limit_count": 5, "rate_limit_minutes": 60 }
749
-
750
- // Request (mailbox worker)
751
- { "tags": ["urgent", "linkedin-batch"] }
752
-
753
- // Response
754
- { "success": true, "status": "active", "tags": ["urgent", "linkedin-batch"] }
755
181
  ```
756
-
757
- Owner can set `priority`, `status` (`"active"` to approve a pending mailbox, `"inactive"` to disable it), and a per-worker rate limit override: `rate_limit_count` + `rate_limit_minutes` (max N proofs/claims per M minutes; both positive integers, or both `null` to revert to the gig's `default_rate_limit_*`). The mailbox's worker can set `tags` — arbitrary free-form labels for organizing their inbox (replaces the full list; max 25 tags, 256 chars each). Tags are private to the worker: they are never returned to the gig owner via `GET /gigs/:id/mailboxes`.
758
-
759
- #### GET /mailboxes/mine
760
-
761
- ```json
762
- // Response
763
- {
764
- "mailboxes": [
765
- {
766
- "id": "...", "name": "...", "gig_id": "GIG_...", "status": "active",
767
- "gig_title": "...", "gig_email": "...", "owner_email": "...", "owner_display_name": "...",
768
- "tasks_received": 12, "proofs_submitted": 10, "response_rate": 0.83,
769
- "tags": ["urgent", "linkedin-batch"]
770
- }
771
- ]
772
- }
182
+ Client Gigworker
183
+ │ │
184
+ ├─ creates a gig, funds it with USDC │
185
+ ├─ mints an invite link ──────────────────────▶│ joins, gets a mailbox
186
+ ├─ sends tasks (webhook or email) │
187
+ │ │ │
188
+ │ └─ pushed to mailboxes ───────────────▶│ receives, or polls a queue
189
+ │ ├─ does the work
190
+ │◀──────────────────────────────────────────────┤ submits a proof
191
+ ├─ approves (or the review timeout does) │
192
+ ├─ triggers a rollup (or the daily cron does) │
193
+ └─ USDC pays out on Base ─────────────────────▶ │ paid_out_at is stamped
773
194
  ```
774
195
 
775
- Supports `?tag=` filtering by case-insensitive **substring** match against your tags — `?tag=link` matches a mailbox tagged `"linkedin-batch"`. Comma-separated values are OR'd: `?tag=urgent,linkedin`.
196
+ Every settled action writes an immutable event against a wallet, readable at
197
+ `GET /reputation/:wallet/events`. That ledger is the only signal this platform publishes — it does
198
+ not score or rate anyone. There is no dispute resolution, and no funds can be reversed.
776
199
 
777
- #### GET /mailboxes/:mbxId/inbound
200
+ An **order machine** runs the same picture backwards:
778
201
 
779
- ```json
780
- // Response
781
- {
782
- "inbound_messages": [
783
- {
784
- "id": "...", "type": "email", "subject": "...", "from": "sender@example.com",
785
- "payload": "...", "mailbox_id": "...", "forwarded_at": "...",
786
- "attachments": [{ "filename": "...", "content_type": "...", "url": "https://..." }]
787
- }
788
- ]
789
- }
790
202
  ```
791
-
792
- ### Proofs
793
-
794
- | Method | Path | Auth | Description |
795
- |--------|------|------|-------------|
796
- | POST | `/gigs/:id/proofs` | Yes | Submit proof of work |
797
- | GET | `/gigs/:id/proofs` | Yes | List proofs (filterable by status) |
798
- | GET | `/gigs/:id/proofs/:proof_id` | Yes | Get proof detail |
799
- | PATCH | `/gigs/:id/proofs/:proof_id` | Yes | Approve or reject proof (owner only) |
800
- | POST | `/gigs/:id/proofs/:proof_id/report` | Yes | Report auto-approved proof (owner only) |
801
-
802
- #### POST /gigs/:id/proofs (Submit Proof)
803
-
804
- ```json
805
- // Request
806
- {
807
- "mailbox_id": "01HX...",
808
- "task_identifier": "reddit-thread-abc123",
809
- "proofs": ["https://reddit.com/r/...", "https://s3.amazonaws.com/..."]
810
- }
811
-
812
- // Response
813
- {
814
- "proof": {
815
- "id": "01HX...",
816
- "status": "pending",
817
- "timeout_at": "2026-02-18T..."
818
- },
819
- "warning": "Warning: gig available funds are less than the task price"
820
- }
203
+ Participant (buys) Vendor (owns the machine, does the work)
204
+ │ │
205
+ ├─ joins by invite, gets a mailbox │
206
+ ├─ saves a draft order through the webhook │
207
+ ├─ publishes it WITH a USDC deposit ──────────▶ │ receives it in their own mailbox
208
+ │ (the deposit and the send are one call)├─ does the work
209
+ │◀──────────────────────────────────────────────┤ delivers a proof, deliverable withheld
210
+ ├─ reads the evidence │
211
+ ├─ may UNDO and take the deposit back ──────────┤ …and so may the vendor, until here
212
+ ├─ approves (or the review timeout does) ◀── the point of no return
213
+ ├─ either party triggers the rollup │
214
+ └─ USDC pays out on Base ─────────────────────▶ │ paid_out_at is stamped
215
+ └─ private_note is released to the buyer
821
216
  ```
822
-
823
- **`task_identifier` is critical.** This field links a proof to the specific task it fulfills.
824
- - For **`queue` gigs**, pass the polled task's `id` (the inbound message ULID returned by `/queue/poll`). The server uses this to atomically claim the queue item out of the queue to your mailbox.
825
- - For **`inbound_proof` gigs** and other distribution modes, use the task's unique reference (URL, ticket ID, publisher-supplied `task_id`, etc.).
826
- - **Avoid using the subject line** — subjects are rarely unique, and collisions cause duplicate-submission 409s.
827
-
828
- The `warning` field appears when the gig's `available_funds` is less than the task price. The proof is still accepted, but payout will fail until the client deposits more funds.
829
-
830
- Price is locked at submission time (`locked_price`).
831
-
832
- #### PATCH /gigs/:id/proofs/:proof_id (Review)
833
-
834
- ```json
835
- // Request (approve)
836
- { "action": "approve", "feedback": "Great work!" }
837
-
838
- // Request (reject)
839
- { "action": "reject", "feedback": "Screenshot doesn't match", "rejection_tag": "incomplete" }
840
-
841
- // Response
842
- { "success": true, "status": "approved" }
843
- ```
844
-
845
- Rejection tags (required when rejecting): `low_quality`, `incomplete`, `fake_proof`, `duplicate`, `unresponsive`, `other`
846
-
847
- Rejection weights (reputation impact): fake_proof=5x, duplicate=3x, incomplete=2x, unresponsive=2x, low_quality=1x, other=1x
848
-
849
- #### POST /gigs/:id/proofs/:proof_id/report (Owner Only)
850
-
851
- ```json
852
- // Response
853
- { "success": true, "status": "reported" }
854
- ```
855
-
856
- Only works on `timeout_approved` proofs. Reported proofs are excluded from rollups and will not be paid.
857
-
858
- ### Rollups (Payouts)
859
-
860
- | Method | Path | Auth | Description |
861
- |--------|------|------|-------------|
862
- | GET | `/gigs/:id/rollups` | Yes | List rollups for gig |
863
- | POST | `/gigs/:id/rollups` | Yes | Trigger manual rollup (owner only) |
864
- | GET | `/rollups/mine` | Yes | List rollups across user's mailboxes |
865
-
866
- #### POST /gigs/:id/rollups (Trigger Payout)
867
-
868
- ```json
869
- // Response
870
- {
871
- "rollups": [
872
- {
873
- "id": "...",
874
- "mailbox_id": "...",
875
- "wallet_address": "0x...",
876
- "proof_ids": ["...", "..."],
877
- "gross_amount": 5.00,
878
- "platform_fee": 0.50,
879
- "net_amount": 5.00,
880
- "tx_hash": "0x...",
881
- "status": "paid"
882
- }
883
- ],
884
- "available_funds": 44.50,
885
- "skipped_below_minimum": [
886
- { "mailbox_id": "...", "amount": 0.50 }
887
- ]
888
- }
889
- ```
890
-
891
- Groups approved + timeout_approved proofs by mailbox. Pre-checks `available_funds >= gross_amount + platform_fee` (no debt allowed). Worker receives full `gross_amount`. Skips mailboxes below `min_payout` threshold.
892
-
893
- **Will return 400 error if the gig cannot cover the total cost (gross + 10% fee).**
894
-
895
- ### Inbound (Task Distribution)
896
-
897
- | Method | Path | Auth | Description |
898
- |--------|------|------|-------------|
899
- | POST | `/inbound/email` | No | Resend inbound email webhook |
900
- | POST | `/inbound/webhook/:gig_id` | No | Publisher webhook task delivery |
901
-
902
- #### POST /inbound/webhook/:gig_id?token=...
903
-
904
- **This is the preferred endpoint for AI agents and publisher apps to deliver tasks.** Accepts **JSON** (default) or **HTML/plain text** payloads. Content-Type header determines parsing.
905
-
906
- **For AI agents:** Use `Content-Type: text/html` with the dual-format HTML pattern (see "Dual-Format HTML" section above) to deliver tasks that work for both human gigworkers and AI agents. Include a hidden `div.agent-data` with `data-agent-json` for structured data extraction.
907
-
908
- **JSON payload (Content-Type: application/json):**
909
-
910
- ```json
911
- // Request
912
- { "task": "Comment on this Reddit thread", "url": "https://..." }
913
-
914
- // Response
915
- { "status": "forwarded", "targets": 3 }
916
- ```
917
-
918
- **HTML payload (Content-Type: text/html or text/plain) — recommended for mixed human+agent gigs:**
919
-
920
- ```bash
921
- curl -X POST "https://dollarplatoon.com/api/inbound/webhook/GIG_01HX...?token=abc123&subject=My+Report" \
922
- -H "Content-Type: text/html" \
923
- -d '<h1>Task Details</h1><p>Please complete this task...</p>'
924
- ```
925
-
926
- ```json
927
- // Response
928
- { "status": "forwarded", "targets": 3 }
929
- ```
930
-
931
- When HTML/text is sent, the message is stored with `type: "email"` and rendered as formatted HTML on the frontend (same as email-sourced tasks). An optional `subject` query parameter can be included to set the message subject line.
932
-
933
- Requires valid `token` query parameter matching the gig's security token. Returns 403 if token is invalid. Selects mailboxes via distribution algorithm, forwards payload to each mailbox webhook.
934
-
935
- **Distribution Modes:**
936
-
937
- - **round_robin** — Cursor-based fair rotation through active mailboxes
938
- - **random** — Uniform random selection
939
- - **priority_weighted** — Weighted by mailbox priority (1-10, higher = more tasks)
940
- - **free_for_all** — All active mailboxes receive the task
941
- - **queue** — Tasks stored in a shared queue; workers poll and claim tasks on-demand
942
- - **inbound_proof** — No tasks distributed; workers submit proofs directly without task assignment
943
-
944
- ### Queue (FIFO)
945
-
946
- | Method | Path | Auth | Description |
947
- |--------|------|------|-------------|
948
- | POST | `/gigs/:id/queue/poll` | Yes | Poll for available tasks (gigworker, queue gigs only) |
949
- | POST | `/gigs/:id/queue/:msgId/decline` | Yes | Skip a task so future polls don't return it to you (per-worker, does not hide from other workers) |
950
- | GET | `/gigs/:id/queue` | Yes | List queued tasks (owner sees `declined_count` per item) |
951
- | DELETE | `/gigs/:id/tasks/:taskId` | Yes | Delete a stored task/inbound message (gig owner only) |
952
-
953
- #### POST /gigs/:id/queue/poll
954
-
955
- ```json
956
- // Request
957
- { "count": 2 } // optional, default 2, max 20
958
-
959
- // Response
960
- {
961
- "tasks": [
962
- {
963
- "id": "...", "type": "webhook", "subject": "...",
964
- "payload": "...", "forwarded_at": "..."
965
- }
966
- ],
967
- "count": 1,
968
- "rate_limit": { "count": 5, "minutes": 60, "source": "gig", "used": 3, "remaining": 2, "retry_at": null } // null if no limit configured
969
- }
970
- ```
971
-
972
- For `queue` gigs only. Returns unclaimed queued tasks in the configured queue order, skipping items you've already submitted a proof for or declined. Tasks are not forwarded to mailboxes — gigworkers must poll to claim them.
973
-
974
- If the gig (or your mailbox specifically) has a worker rate limit, polling past it returns `429` with an `error` message stating the limit and how long to wait, plus the same `rate_limit` object with `retry_at` set. Claims are capped to your remaining allowance — e.g. requesting 10 tasks with 2 remaining returns at most 2.
975
-
976
- #### POST /gigs/:id/queue/:msgId/decline
977
-
978
- Marks a queue item as skipped *for the calling worker only*. Idempotent. Returns `{"success": true}`.
979
-
980
- Use this when a polled task isn't suitable for you (spam, duplicate, ineligible, etc.) so future polls return fresh items instead of the same ones at the head of the FIFO queue. Other workers still see the item. The gig owner sees a `declined_count` on their dashboard so they can prune genuinely unworkable items.
981
-
982
- **For Gigworkers (Queue gigs):**
983
-
984
- - Tasks are NOT forwarded to your mailbox. Instead, use "Poll New Tasks" in the UI or call `POST /gigs/:id/queue/poll` to claim tasks from the shared queue.
985
- - Tasks are returned in the configured queue order (FIFO or LIFO) and filtered against proofs you've already submitted or items you've declined.
986
- - After polling, submit proofs via `POST /gigs/:id/proofs` using the polled task's `id` as `task_identifier` — this atomically claims the queue item into your mailbox.
987
- - If a task isn't suitable, call `POST /gigs/:id/queue/:msgId/decline` to skip it. Declining is free and doesn't affect other workers.
988
-
989
- ### Public (No Auth Required)
990
-
991
- | Method | Path | Auth | Description |
992
- |--------|------|------|-------------|
993
- | GET | `/public/mailbox-info?token=...` | No | Get mailbox info via share token |
994
- | POST | `/public/upload-presign` | No | Get S3 presigned upload URL |
995
- | POST | `/public/submit-proof` | No | Submit proof via public share link |
996
- | GET | `/public/read-url?key=...&token=...` | No | Get presigned S3 read URL |
997
-
998
- Rate limited: 10-30 requests/min per share token.
999
-
1000
- #### POST /public/submit-proof
1001
-
1002
- ```json
1003
- // Request
1004
- {
1005
- "share_token": "tok_...",
1006
- "task_identifier": "reddit-thread-abc123",
1007
- "proofs": ["https://..."]
1008
- }
1009
-
1010
- // Response
1011
- { "proof_id": "...", "status": "pending" }
1012
- ```
1013
-
1014
- ### Reviews
1015
-
1016
- | Method | Path | Auth | Description |
1017
- |--------|------|------|-------------|
1018
- | POST | `/gigs/:id/reviews` | Yes | Leave star review (1-5) |
1019
- | PATCH | `/reviews/:id/resolve` | Yes | Mark review as resolved (reviewer only) |
1020
- | GET | `/reputation/:wallet/reviews` | No | List reviews for wallet |
1021
-
1022
- #### POST /gigs/:id/reviews
1023
-
1024
- ```json
1025
- // Request
1026
- { "target_wallet": "0x...", "stars": 4, "comment": "Reliable worker, good quality" }
1027
-
1028
- // Response
1029
- { "review": { "id": "...", "stars": 4 } }
1030
- ```
1031
-
1032
- One review per reviewer-target pair per gig. Reviewer role auto-detected (client if owner, gigworker otherwise).
1033
-
1034
- ### Reputation
1035
-
1036
- | Method | Path | Auth | Description |
1037
- |--------|------|------|-------------|
1038
- | GET | `/reputation/:wallet` | No | Get computed reputation score |
1039
- | GET | `/reputation/alias/:alias_id` | No | Get reputation by wallet alias |
1040
- | GET | `/reputation/:wallet/events` | No | List raw reputation events |
1041
-
1042
- #### GET /reputation/:wallet
1043
-
1044
- ```json
1045
- // Response
1046
- {
1047
- "wallet": "0x...",
1048
- "volume": 150.50,
1049
- "quality": 0.92,
1050
- "recency": 0.85,
1051
- "social": 4.2,
1052
- "event_count": 47
1053
- }
1054
- ```
1055
-
1056
- ### Wallets
1057
-
1058
- | Method | Path | Auth | Description |
1059
- |--------|------|------|-------------|
1060
- | POST | `/wallets` | Yes | Create wallet alias |
1061
- | GET | `/wallets` | Yes | List user's wallet aliases |
1062
- | GET | `/wallets/:alias_id` | Yes | Get wallet detail |
1063
- | GET | `/wallets/:alias_id/balances` | Yes | Get on-chain balances (ETH + USDC) |
1064
- | POST | `/wallets/:alias_id/transfer` | Yes | Transfer USDC from hot wallet |
1065
- | DELETE | `/wallets/:alias_id` | Yes | Delete wallet alias |
1066
-
1067
- #### POST /wallets
1068
-
1069
- ```json
1070
- // Request (hot wallet — platform-managed)
1071
- { "label": "My Hot Wallet", "is_hot_wallet": true }
1072
-
1073
- // Request (external wallet — self-custody)
1074
- { "label": "My MetaMask", "is_hot_wallet": false, "evm_address": "0x..." }
1075
-
1076
- // Response
1077
- { "wallet": { "alias_id": "...", "label": "My Hot Wallet", "is_hot_wallet": true, "created_at": "..." } }
1078
- ```
1079
-
1080
- One hot wallet per user. External wallets are unlimited.
1081
-
1082
- #### GET /wallets/:alias_id/balances
1083
-
1084
- ```json
1085
- // Response
1086
- { "evm_address": "0x...", "eth_balance": "0.05", "usdc_balance": "100.000000" }
1087
- ```
1088
-
1089
- #### POST /wallets/:alias_id/transfer
1090
-
1091
- ```json
1092
- // Request
1093
- { "to_address": "0x...", "amount": 50 }
1094
-
1095
- // Response
1096
- { "tx_hash": "0x..." }
1097
- ```
1098
-
1099
- Hot wallets only.
1100
-
1101
- ### Profiles
1102
-
1103
- | Method | Path | Auth | Description |
1104
- |--------|------|------|-------------|
1105
- | PATCH | `/profiles/me` | Yes | Update own profile |
1106
- | GET | `/profiles/:identifier` | No | Get public profile (by email or alias_id) |
1107
- | GET | `/profiles/:identifier/private` | Yes | Get private profile (requires shared gig relationship) |
1108
-
1109
- #### PATCH /profiles/me
1110
-
1111
- ```json
1112
- // Request
1113
- { "display_name": "John Doe", "bio": "Experienced social media marketer", "avatar_url": "https://..." }
1114
- ```
1115
-
1116
- ### Upload
1117
-
1118
- | Method | Path | Auth | Description |
1119
- |--------|------|------|-------------|
1120
- | POST | `/upload/presign` | Yes | Get presigned S3 upload URL |
1121
-
1122
- ```json
1123
- // Request
1124
- { "filename": "screenshot.png", "content_type": "image/png", "prefix": "proofs" }
1125
-
1126
- // Response
1127
- { "presigned_url": "https://s3...", "url": "https://s3...", "key": "proofs/...", "bucket": "..." }
1128
- ```
1129
-
1130
- Prefix options: `"avatars"`, `"gig-icons"`, or `"proofs"` (default). Presigned URL expires in 1 hour.
1131
-
1132
- ### OfficeX Integration
1133
-
1134
- | Method | Path | Auth | Description |
1135
- |--------|------|------|-------------|
1136
- | POST | `/officex/webhook` | No | Handle OfficeX install/uninstall |
1137
- | POST | `/officex/login` | No | Login via OfficeX credentials |
1138
-
1139
- #### POST /officex/webhook
1140
-
1141
- ```json
1142
- // Request
1143
- { "event": "INSTALL", "payload": { "install_id": "...", "install_secret": "...", "user_id": "...", "app_id": "..." } }
1144
-
1145
- // Response
1146
- { "agent_context": { "user_email": "officex-...@dollar-platoon.local", "api_key": "...", "api_url": "https://...", "install_id": "...", "install_secret": "..." } }
1147
- ```
1148
-
1149
- Creates user with email `officex-{user_id}@dollar-platoon.local`. Auto-provisions hot wallet.
1150
-
1151
- #### POST /officex/login
1152
-
1153
- ```json
1154
- // Request
1155
- { "officex_user_id": "...", "officex_install_id": "..." }
1156
-
1157
- // Response
1158
- { "email": "officex-...@dollar-platoon.local", "api_key": "..." }
1159
- ```
1160
-
1161
- Returns 404 if user not found (webhook may not have fired yet). Returns 403 if install_id mismatch.
1162
-
1163
- ### Admin
1164
-
1165
- | Method | Path | Auth | Description |
1166
- |--------|------|------|-------------|
1167
- | POST | `/admin/users/provision` | `x-admin-key` header | Programmatically provision (or fetch) an account |
1168
-
1169
- #### POST /admin/users/provision
1170
-
1171
- Idempotent. Creates the account (and auto-provisions a hot wallet) if the email is new — `201` with `"created": true`. If the account already exists, no changes are made and the existing account info is returned — `200` with `"created": false`. The API key is never rotated by this endpoint.
1172
-
1173
- ```json
1174
- // Request (header: x-admin-key: <ADMIN_API_KEY>)
1175
- { "email": "user@example.com" }
1176
-
1177
- // Response — 201 if newly created, 200 if the account already existed
1178
- {
1179
- "created": false,
1180
- "account": {
1181
- "email": "user@example.com",
1182
- "api_key": "base64url_encoded_key",
1183
- "display_name": null,
1184
- "created_at": "2026-02-14T...",
1185
- "officex_user_id": null,
1186
- "officex_install_id": null
1187
- }
1188
- }
1189
- ```
1190
-
1191
- Returns 503 if `ADMIN_API_KEY` is not configured, 401 if the header is missing, 403 if the key is invalid.
1192
-
1193
- ### Health
1194
-
1195
- | Method | Path | Auth | Description |
1196
- |--------|------|------|-------------|
1197
- | GET | `/health` | No | Health check |
1198
-
1199
- ```json
1200
- { "status": "ok", "stage": "production", "timestamp": "2026-02-14T..." }
1201
- ```
1202
-
1203
- ---
1204
-
1205
- ## Proof Lifecycle
1206
-
1207
- ```
1208
- submitted (locked_price snapshot, timeout_at set)
1209
- → approved (client action) → rolled up → payout on-chain → paid
1210
- → rejected (requires rejection_tag + optional feedback)
1211
- → timeout_approved (daily cron, after review_timeout) → same rollup path
1212
- → reported (post-timeout flag by owner, excluded from payouts)
1213
- ```
1214
-
1215
- Rejection tags: `low_quality`, `incomplete`, `fake_proof`, `duplicate`, `unresponsive`, `other`
1216
-
1217
- ---
1218
-
1219
- ## Rollup & Payout Flow
1220
-
1221
- 1. Client triggers `POST /gigs/:id/rollups` (or daily cron runs automatically)
1222
- 2. Groups approved proofs by mailbox, sums `locked_price` per mailbox
1223
- 3. Skips mailboxes below `min_payout` threshold
1224
- 4. Pre-checks: `gross_amount + platform_fee <= available_funds` — **fails with 400 if underfunded**
1225
- 5. Calls on-chain `payout(gig_id, wallet, gross_amount, rollup_id)`
1226
- 6. On success: stores `tx_hash`, status → `paid`, creates reputation event
1227
- 7. On failure: status → `failed`, retried by next daily cron run