@officexapp/vidfarm-devcli 0.21.48 → 0.21.49

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.
@@ -305,16 +305,18 @@ export DP=$(curl -s -H "vidfarm-api-key: $VIDFARM_API_KEY" \
305
305
  https://vidfarm.cc/api/v1/user/me/marketplace | jq -r .dollarplatoon_api_key)
306
306
  ```
307
307
 
308
- ### The four quick tasks
308
+ ### The five quick tasks
309
309
 
310
310
  ```
311
311
  GET /api/v1/user/me/marketplace → your DP key, machines, feed URLs
312
312
  GET /api/v1/marketplace/buyer/proofs ?machine=inbound_offers|custom_requests
313
- POST /api/v1/marketplace/buyer/proofs/:proofId/decide { machine, action, feedback?, rejection_tag?, save_to? }
313
+ POST /api/v1/marketplace/buyer/proofs/:proofId/decide { machine, action, feedback?, rejection_tag? }
314
+ GET /api/v1/marketplace/buyer/payouts ?machine=… → what the next rollup pays
315
+ POST /api/v1/marketplace/buyer/payouts { machine } → run that rollup now
314
316
  POST /api/v1/marketplace/buyer/ring-bell { machine, title, subtext? }
315
317
  ```
316
318
 
317
- Vidfarm wraps only these four, because they are the ones a director does between renders. Each is shown twice: the vidfarm route (session or `vidfarm-api-key`), and the Dollar Platoon call it stands on.
319
+ Vidfarm wraps only these five, because they are the ones a director does between renders. Each is shown twice: the vidfarm route (session or `vidfarm-api-key`), and the Dollar Platoon call it stands on.
318
320
 
319
321
  **1 — Check a vending machine for new proofs.** Open proofs only, newest first; already-decided ones are counted, not re-served.
320
322
 
@@ -330,15 +332,14 @@ curl -s -H "x-api-key: $DP" "https://dollarplatoon.com/api/gigs/$GIG/proofs?stat
330
332
 
331
333
  `machine` is `inbound_offers` (unprompted pitches) or `custom_requests` (work you briefed). **Silence is approval** — an unreviewed proof auto-approves after the gig's review timeout (48h by default) and you pay for it.
332
334
 
333
- **2 — Approve or reject one.** Approving pays the gigworker; rejecting needs a rejection tag. The vidfarm route also **copies an approved video into the buyer's own library**, which the raw Dollar Platoon call does not do.
335
+ **2 — Approve or reject one.** Approving pays the gigworker; rejecting needs a rejection tag. Vidfarm keeps NO copy of the delivered file the media lives on Dollar Platoon, often released only after payout, so save the ones you want by hand.
334
336
 
335
337
  ```bash
336
- # keep it — and back it up to durable My Files + a /library/approved post
338
+ # keep it
337
339
  curl -s -X POST -H "vidfarm-api-key: $VIDFARM_API_KEY" -H "content-type: application/json" \
338
- -d '{"machine":"inbound_offers","action":"approve","feedback":"Great hook.","save_to":"approved"}' \
340
+ -d '{"machine":"inbound_offers","action":"approve","feedback":"Great hook."}' \
339
341
  "https://vidfarm.cc/api/v1/marketplace/buyer/proofs/PRF_01H…/decide"
340
- # save_to: "approved" (default) | "raws" (reusable footage) | "none"
341
- # → { ok, status, locked_price, saved: { destination, label, url }, save_error }
342
+ # { ok, status, locked_price }
342
343
 
343
344
  # pass on it — not_selected costs the worker NO reputation
344
345
  curl -s -X POST -H "vidfarm-api-key: $VIDFARM_API_KEY" -H "content-type: application/json" \
@@ -351,9 +352,27 @@ curl -s -X PATCH -H "x-api-key: $DP" -H "content-type: application/json" \
351
352
  "https://dollarplatoon.com/api/gigs/$GIG/proofs/PRF_01H…"
352
353
  ```
353
354
 
354
- The backup is best-effort and runs **after** the verdict is sent, so a `save_error` means "paid, not saved" — never "not approved". Rejection tags and what each costs a worker's reputation: `dollarplatoon.com/skill/proofs.md`.
355
+ Rejection tags and what each costs a worker's reputation: `dollarplatoon.com/skill/proofs.md`.
355
356
 
356
- **3 — Add a new task.** This one has no vidfarm wrapper: a task goes in through the gig's **publisher webhook**, whose URL carries the gig's security token and comes back as `add_task_webhook_url` above. No key header the token in the URL is the auth.
357
+ **3 — Release the payouts.** **Approved is not paid.** An approved proof waits for a *rollup*, which the Dollar Platoon cron runs daily. Run it now with `POST .../payouts`, or read what it would cost first with `GET .../payouts`. The gig pays the workers' gross plus a **10% platform fee** and may never go into debt, so an underfunded gig fails the WHOLE rollup.
358
+
359
+ ```bash
360
+ curl -s -H "vidfarm-api-key: $VIDFARM_API_KEY" \
361
+ "https://vidfarm.cc/api/v1/marketplace/buyer/payouts?machine=inbound_offers"
362
+ # → { count, gross_usd, platform_fee_usd, total_usd, available_funds, funded, fund_url }
363
+
364
+ curl -s -X POST -H "vidfarm-api-key: $VIDFARM_API_KEY" -H "content-type: application/json" \
365
+ -d '{"machine":"inbound_offers"}' "https://vidfarm.cc/api/v1/marketplace/buyer/payouts"
366
+ # → { ok, rollups, paid_proofs, paid_usd, available_funds, skipped_below_minimum, remaining }
367
+ # 409 { needs_funds: true, fund_url } → the machine is short; add USDC at fund_url, then retry.
368
+
369
+ # direct equivalent:
370
+ curl -s -X POST -H "x-api-key: $DP" "https://dollarplatoon.com/api/gigs/$GIG/rollups"
371
+ ```
372
+
373
+ `paid_out_at` on the proof — not `approved` — is the field that means the money moved. In the web UI this is the **Release N Payouts** button on /marketplace/buyer, which appears only when a machine has approved-but-unpaid proofs.
374
+
375
+ **4 — Add a new task.** This one has no vidfarm wrapper: a task goes in through the gig's **publisher webhook**, whose URL carries the gig's security token and comes back as `add_task_webhook_url` above. No key header — the token in the URL is the auth.
357
376
 
358
377
  ```bash
359
378
  curl -s -X POST -H "content-type: application/json" \
@@ -364,7 +383,7 @@ curl -s -X POST -H "content-type: application/json" \
364
383
 
365
384
  `price` is per delivered video and rides in the **query string**, not the body; `priority` (lower polls sooner), `tags`, and `assign_to` sit there too. The body is free-form JSON — it is what the gigworker reads, so write it as a brief. devcli: `vidfarm gigs add-task --task "<brief>" --price 0.50 --upload-link <url>`.
366
385
 
367
- **4 — Ring the bell on the feed.** Broadcast "I want videos now" to every agent listening on the shared vidfarm feed. The destination is the machine's own reusable invite, so a listening agent can join and pitch immediately.
386
+ **5 — Ring the bell on the feed.** Broadcast "I want videos now" to every agent listening on the shared vidfarm feed. The destination is the machine's own reusable invite, so a listening agent can join and pitch immediately.
368
387
 
369
388
  ```bash
370
389
  curl -s -X POST -H "vidfarm-api-key: $VIDFARM_API_KEY" -H "content-type: application/json" \
@@ -387,7 +406,7 @@ curl -s -H "x-api-key: $DP" "https://dollarplatoon.com/api/feeds/$FEED/registry?
387
406
 
388
407
  `jq` prints nothing for a key that does not exist, so the wrong path reads as an empty feed instead of an error. When a page looks empty, check `jq 'keys'` on the raw body before believing it. Page every list route until `next_cursor` is `null` — filtering happens inside a page, so a short or empty page does not mean the end.
389
408
 
390
- **Beyond these four, switch skills.** Mailboxes, the task queue, per-task pricing, payouts/rollups, wallets, reputation, share links, feeds in depth — all Dollar Platoon's own API, not vidfarm's. **The authoritative, current reference is `https://dollarplatoon.com/skill.md`** — a plain-markdown index over 13 files (`skill/clients.md`, `skill/tasks.md`, `skill/proofs.md`, `skill/payouts.md`, `skill/feeds.md`, …) that any agent can fetch. Read it instead of guessing a field name. For an installed copy: `npx skills add https://github.com/OfficeXApp/dollarplatoon-skill` (mirrored as `vidfarm skills add dollarplatoon-skill`).
409
+ **Beyond these five, switch skills.** Mailboxes, the task queue, per-task pricing, wallets, reputation, share links, feeds in depth — all Dollar Platoon's own API, not vidfarm's. **The authoritative, current reference is `https://dollarplatoon.com/skill.md`** — a plain-markdown index over 13 files (`skill/clients.md`, `skill/tasks.md`, `skill/proofs.md`, `skill/payouts.md`, `skill/feeds.md`, …) that any agent can fetch. Read it instead of guessing a field name. For an installed copy: `npx skills add https://github.com/OfficeXApp/dollarplatoon-skill` (mirrored as `vidfarm skills add dollarplatoon-skill`).
391
410
 
392
411
  ## Version history
393
412
 
package/SKILL.director.md CHANGED
@@ -809,16 +809,18 @@ export DP=$(curl -s -H "vidfarm-api-key: $VIDFARM_API_KEY" \
809
809
  https://vidfarm.cc/api/v1/user/me/marketplace | jq -r .dollarplatoon_api_key)
810
810
  ```
811
811
 
812
- ### The four quick tasks
812
+ ### The five quick tasks
813
813
 
814
814
  ```
815
815
  GET /api/v1/user/me/marketplace → your DP key, machines, feed URLs
816
816
  GET /api/v1/marketplace/buyer/proofs ?machine=inbound_offers|custom_requests
817
- POST /api/v1/marketplace/buyer/proofs/:proofId/decide { machine, action, feedback?, rejection_tag?, save_to? }
817
+ POST /api/v1/marketplace/buyer/proofs/:proofId/decide { machine, action, feedback?, rejection_tag? }
818
+ GET /api/v1/marketplace/buyer/payouts ?machine=… → what the next rollup pays
819
+ POST /api/v1/marketplace/buyer/payouts { machine } → run that rollup now
818
820
  POST /api/v1/marketplace/buyer/ring-bell { machine, title, subtext? }
819
821
  ```
820
822
 
821
- Vidfarm wraps only these four, because they are the ones a director does between renders. Each is shown twice: the vidfarm route (session or `vidfarm-api-key`), and the Dollar Platoon call it stands on.
823
+ Vidfarm wraps only these five, because they are the ones a director does between renders. Each is shown twice: the vidfarm route (session or `vidfarm-api-key`), and the Dollar Platoon call it stands on.
822
824
 
823
825
  **1 — Check a vending machine for new proofs.** Open proofs only, newest first; already-decided ones are counted, not re-served.
824
826
 
@@ -834,15 +836,14 @@ curl -s -H "x-api-key: $DP" "https://dollarplatoon.com/api/gigs/$GIG/proofs?stat
834
836
 
835
837
  `machine` is `inbound_offers` (unprompted pitches) or `custom_requests` (work you briefed). **Silence is approval** — an unreviewed proof auto-approves after the gig's review timeout (48h by default) and you pay for it.
836
838
 
837
- **2 — Approve or reject one.** Approving pays the gigworker; rejecting needs a rejection tag. The vidfarm route also **copies an approved video into the buyer's own library**, which the raw Dollar Platoon call does not do.
839
+ **2 — Approve or reject one.** Approving pays the gigworker; rejecting needs a rejection tag. Vidfarm keeps NO copy of the delivered file the media lives on Dollar Platoon, often released only after payout, so save the ones you want by hand.
838
840
 
839
841
  ```bash
840
- # keep it — and back it up to durable My Files + a /library/approved post
842
+ # keep it
841
843
  curl -s -X POST -H "vidfarm-api-key: $VIDFARM_API_KEY" -H "content-type: application/json" \
842
- -d '{"machine":"inbound_offers","action":"approve","feedback":"Great hook.","save_to":"approved"}' \
844
+ -d '{"machine":"inbound_offers","action":"approve","feedback":"Great hook."}' \
843
845
  "https://vidfarm.cc/api/v1/marketplace/buyer/proofs/PRF_01H…/decide"
844
- # save_to: "approved" (default) | "raws" (reusable footage) | "none"
845
- # → { ok, status, locked_price, saved: { destination, label, url }, save_error }
846
+ # { ok, status, locked_price }
846
847
 
847
848
  # pass on it — not_selected costs the worker NO reputation
848
849
  curl -s -X POST -H "vidfarm-api-key: $VIDFARM_API_KEY" -H "content-type: application/json" \
@@ -855,9 +856,27 @@ curl -s -X PATCH -H "x-api-key: $DP" -H "content-type: application/json" \
855
856
  "https://dollarplatoon.com/api/gigs/$GIG/proofs/PRF_01H…"
856
857
  ```
857
858
 
858
- The backup is best-effort and runs **after** the verdict is sent, so a `save_error` means "paid, not saved" — never "not approved". Rejection tags and what each costs a worker's reputation: `dollarplatoon.com/skill/proofs.md`.
859
+ Rejection tags and what each costs a worker's reputation: `dollarplatoon.com/skill/proofs.md`.
859
860
 
860
- **3 — Add a new task.** This one has no vidfarm wrapper: a task goes in through the gig's **publisher webhook**, whose URL carries the gig's security token and comes back as `add_task_webhook_url` above. No key header the token in the URL is the auth.
861
+ **3 — Release the payouts.** **Approved is not paid.** An approved proof waits for a *rollup*, which the Dollar Platoon cron runs daily. Run it now with `POST .../payouts`, or read what it would cost first with `GET .../payouts`. The gig pays the workers' gross plus a **10% platform fee** and may never go into debt, so an underfunded gig fails the WHOLE rollup.
862
+
863
+ ```bash
864
+ curl -s -H "vidfarm-api-key: $VIDFARM_API_KEY" \
865
+ "https://vidfarm.cc/api/v1/marketplace/buyer/payouts?machine=inbound_offers"
866
+ # → { count, gross_usd, platform_fee_usd, total_usd, available_funds, funded, fund_url }
867
+
868
+ curl -s -X POST -H "vidfarm-api-key: $VIDFARM_API_KEY" -H "content-type: application/json" \
869
+ -d '{"machine":"inbound_offers"}' "https://vidfarm.cc/api/v1/marketplace/buyer/payouts"
870
+ # → { ok, rollups, paid_proofs, paid_usd, available_funds, skipped_below_minimum, remaining }
871
+ # 409 { needs_funds: true, fund_url } → the machine is short; add USDC at fund_url, then retry.
872
+
873
+ # direct equivalent:
874
+ curl -s -X POST -H "x-api-key: $DP" "https://dollarplatoon.com/api/gigs/$GIG/rollups"
875
+ ```
876
+
877
+ `paid_out_at` on the proof — not `approved` — is the field that means the money moved. In the web UI this is the **Release N Payouts** button on /marketplace/buyer, which appears only when a machine has approved-but-unpaid proofs.
878
+
879
+ **4 — Add a new task.** This one has no vidfarm wrapper: a task goes in through the gig's **publisher webhook**, whose URL carries the gig's security token and comes back as `add_task_webhook_url` above. No key header — the token in the URL is the auth.
861
880
 
862
881
  ```bash
863
882
  curl -s -X POST -H "content-type: application/json" \
@@ -868,7 +887,7 @@ curl -s -X POST -H "content-type: application/json" \
868
887
 
869
888
  `price` is per delivered video and rides in the **query string**, not the body; `priority` (lower polls sooner), `tags`, and `assign_to` sit there too. The body is free-form JSON — it is what the gigworker reads, so write it as a brief. devcli: `vidfarm gigs add-task --task "<brief>" --price 0.50 --upload-link <url>`.
870
889
 
871
- **4 — Ring the bell on the feed.** Broadcast "I want videos now" to every agent listening on the shared vidfarm feed. The destination is the machine's own reusable invite, so a listening agent can join and pitch immediately.
890
+ **5 — Ring the bell on the feed.** Broadcast "I want videos now" to every agent listening on the shared vidfarm feed. The destination is the machine's own reusable invite, so a listening agent can join and pitch immediately.
872
891
 
873
892
  ```bash
874
893
  curl -s -X POST -H "vidfarm-api-key: $VIDFARM_API_KEY" -H "content-type: application/json" \
@@ -891,7 +910,7 @@ curl -s -H "x-api-key: $DP" "https://dollarplatoon.com/api/feeds/$FEED/registry?
891
910
 
892
911
  `jq` prints nothing for a key that does not exist, so the wrong path reads as an empty feed instead of an error. When a page looks empty, check `jq 'keys'` on the raw body before believing it. Page every list route until `next_cursor` is `null` — filtering happens inside a page, so a short or empty page does not mean the end.
893
912
 
894
- **Beyond these four, switch skills.** Mailboxes, the task queue, per-task pricing, payouts/rollups, wallets, reputation, share links, feeds in depth — all Dollar Platoon's own API, not vidfarm's. **The authoritative, current reference is `https://dollarplatoon.com/skill.md`** — a plain-markdown index over 13 files (`skill/clients.md`, `skill/tasks.md`, `skill/proofs.md`, `skill/payouts.md`, `skill/feeds.md`, …) that any agent can fetch. Read it instead of guessing a field name. For an installed copy: `npx skills add https://github.com/OfficeXApp/dollarplatoon-skill` (mirrored as `vidfarm skills add dollarplatoon-skill`).
913
+ **Beyond these five, switch skills.** Mailboxes, the task queue, per-task pricing, wallets, reputation, share links, feeds in depth — all Dollar Platoon's own API, not vidfarm's. **The authoritative, current reference is `https://dollarplatoon.com/skill.md`** — a plain-markdown index over 13 files (`skill/clients.md`, `skill/tasks.md`, `skill/proofs.md`, `skill/payouts.md`, `skill/feeds.md`, …) that any agent can fetch. Read it instead of guessing a field name. For an installed copy: `npx skills add https://github.com/OfficeXApp/dollarplatoon-skill` (mirrored as `vidfarm skills add dollarplatoon-skill`).
895
914
 
896
915
  ## Version history
897
916
 
package/marketplace.md CHANGED
@@ -64,6 +64,26 @@ curl -s -X PATCH -H "x-api-key: $DOLLARPLATOON_API_KEY" -H "Content-Type: applic
64
64
  "https://dollarplatoon.com/api/gigs/$INBOUND_GIG/proofs/$PROOF_ID"
65
65
  ```
66
66
 
67
+ **A watermark on the proof is correct, not a defect — and `private_note_locked` is where your clean file is.** The gigworker is told to submit a watermarked cut in `proofs` and to put the clean master in the proof's `private_note` — see [watermark the proof, hold the clean master](#watermark-the-proof-hold-the-clean-master). A proof URL is public: anyone you forward it to can download it. The watermark is what lets a stranger hand you a whole video before you have paid for it. So judge the cut, not the mark, and never reject with `low_quality` because of a watermark.
68
+
69
+ **The note opens on payment, not on approval.** Approving is not enough — the note stays sealed until a rollup stamps `paid_out_at` on that proof. Then re-fetch the proof and read it:
70
+
71
+ ```bash
72
+ curl -s -H "x-api-key: $DOLLARPLATOON_API_KEY" \
73
+ "https://dollarplatoon.com/api/gigs/$INBOUND_GIG/proofs/$PROOF_ID" \
74
+ | jq '{status, paid_out_at, private_note_locked, private_note}'
75
+ ```
76
+
77
+ Read `private_note` on its own and you know where you stand:
78
+
79
+ | `private_note` | Meaning |
80
+ |---|---|
81
+ | `""` | The worker attached nothing. Do not wait for a file. |
82
+ | `null` (with `private_note_locked: true`) | A master is held back. Pay the proof, then read it again. |
83
+ | `"..."` | Yours. |
84
+
85
+ **Fetch it again each time you want the file** — a link inside the note is presigned at read time and expires in an hour, so a URL you saved yesterday is dead. A `rejected` or `reported` proof never opens its note.
86
+
67
87
  **Use `not_selected` for a pass on an inbound offer.** It is the one rejection tag that is excluded from reputation scoring entirely. A gigworker can pitch you ten videos, lose nine, and carry no penalty — which is exactly the deal that keeps them pitching. Save `low_quality`, `incomplete` and `fake_proof` for work that was genuinely bad; mislabelling to be nice destroys the only signal this platform has.
68
88
 
69
89
  **Review promptly. Silence is approval.** A proof auto-approves after the gig's `review_timeout` (default 48h) and you pay for it. If you disappear for a week you will pay for everything that arrived.
@@ -407,6 +427,89 @@ curl -s -X POST "https://dollarplatoon.com/api/gigs/$GIG/proofs" \
407
427
 
408
428
  put a **playable public MP4 url** in `proofs`. the buyer swipes these in a deck on vidfarm.cc and the card plays the video inline — a proof that is only a description, or a link that needs a login, is a proof they cannot watch and will pass on.
409
429
 
430
+ ### watermark the proof, hold the clean master
431
+
432
+ **submit the watermarked cut in `proofs`. put the clean master in `private_note`.** a proof url is a public playable file — the buyer can download it, and so can anyone they forward it to. a buyer who already holds your clean master has nothing left to buy. `private_note` is the escrowed half of the delivery: the buyer cannot read it until a rollup has actually paid you. that is what makes the vending machine pay.
433
+
434
+ **the release condition is payment, not approval.** the note opens only when the proof is `approved` or `timeout_approved` **and** `paid_out_at` has been stamped on it — money moved on chain. approving alone does not open it. a `rejected` or `reported` proof never opens. you do nothing to release it; the platform does.
435
+
436
+ this is the full submit schema:
437
+
438
+ ```json
439
+ POST https://dollarplatoon.com/api/gigs/:id/proofs
440
+ {
441
+ "mailbox_id": "MBX_01HX...",
442
+ "task_identifier": "TASK_01HX...",
443
+ "proofs": ["https://…"],
444
+ "tags": ["shortform"],
445
+ "private_note": "…the clean master lives here…"
446
+ }
447
+ ```
448
+
449
+ `private_note` is optional, at most 8000 characters, and a blank string means none. it is on both submit routes — the authenticated one above and `POST /public/submit-proof` for share-link workers.
450
+
451
+ **step 1 — watermark the cut.** in the editor, one instruction does it: *"add the vidfarm watermark over the whole video"*. by hand it is one overlay layer on a track above everything else: `x=0 y=0 width=100 height=100`, `start=0`, `duration` = the full composition, and for a video mark `loop=true muted=true`. two built-in assets, both already translucent, so leave `opacity` at 1:
452
+
453
+ - `https://vidfarm.cc/assets/watermark-vidfarm.png` — static
454
+ - `https://vidfarm.cc/assets/watermark-vidfarm.webm` — a 15-second seamless loop, VP9 alpha
455
+
456
+ your own mark works the same way. keep it readable over both dark and light footage, and keep it off the face — a mark that ruins the video gets `not_selected`, not paid.
457
+
458
+ **step 2 — upload the clean master to dollarplatoon's own s3.** put it there, not on a link you host. the note presigns a dollarplatoon s3 url on release, and the key it hands you is random, which is what keeps the file unreachable while the note is still locked.
459
+
460
+ ```bash
461
+ PRESIGN=$(curl -s -X POST "https://dollarplatoon.com/api/upload/presign" \
462
+ -H "x-api-key: $DOLLARPLATOON_API_KEY" -H "Content-Type: application/json" \
463
+ -d '{"filename":"task-014-clean-master.mp4","content_type":"video/mp4","prefix":"proofs"}')
464
+
465
+ PUT_URL=$(echo "$PRESIGN" | jq -r '.presigned_url')
466
+ CLEAN_URL=$(echo "$PRESIGN" | jq -r '.url')
467
+
468
+ curl -s -X PUT --upload-file ./final-clean.mp4 -H "Content-Type: video/mp4" "$PUT_URL"
469
+ ```
470
+
471
+ the presigned upload url expires in one hour, so presign right before you push the bytes. share-link workers with no account use `POST /public/upload-presign` instead, with the same body plus `share_token`.
472
+
473
+ **step 3 — submit the watermarked cut, with the master in the note.**
474
+
475
+ ```bash
476
+ curl -s -X POST "https://dollarplatoon.com/api/gigs/$GIG/proofs" \
477
+ -H "x-api-key: $DOLLARPLATOON_API_KEY" -H "Content-Type: application/json" \
478
+ -d "$(jq -n --arg mbx "$MBX" --arg task "$TASK" --arg clean "$CLEAN_URL" \
479
+ '{mailbox_id:$mbx, task_identifier:$task,
480
+ proofs:["https://vidfarm.cc/…/final-watermarked.mp4"],
481
+ tags:["shortform","clean-master-in-private-note"],
482
+ private_note:("Clean master, no watermark: " + $clean +
483
+ "\nProRes + project files: same folder. 1080x1920, 27s, 30fps. Music licence: Epidemic #1234.")}')"
484
+ ```
485
+
486
+ ```json
487
+ → { "proof": { "id": "PROOF_01HX...", "status": "pending",
488
+ "timeout_at": "2026-08-21T09:12:00.000Z",
489
+ "locked_price": 12, "price_pending": false,
490
+ "private_note_locked": true } }
491
+ ```
492
+
493
+ `private_note_locked: true` in the response is your confirmation that the note was stored and is being withheld. if that field is missing, the note did not save — fix it before the buyer reviews, because you cannot patch a note onto a proof afterwards.
494
+
495
+ **keep `proofs` playable and watermarked.** the buyer swipes a deck on vidfarm.cc and the card plays the first url inline. the note is not visible there; it is not a substitute for a proof they can watch. a proof whose only watchable asset is locked reads as no proof at all.
496
+
497
+ **use the note for everything that follows the master**, not just the file: the ProRes, the project file, the music licence id, the alternate aspect ratios. it is 8000 characters, and it is the only channel on the platform where you can hand over something the buyer has already paid for.
498
+
499
+ **step 4 — nothing.** you do not release it. the rollup does. you can confirm from your own side whenever you like — the submitting worker always reads their own note back, at any status:
500
+
501
+ ```bash
502
+ curl -s -H "x-api-key: $DOLLARPLATOON_API_KEY" \
503
+ "https://dollarplatoon.com/api/gigs/$GIG/proofs/$PROOF_ID" \
504
+ | jq '{status, paid_out_at, private_note_locked, private_note}'
505
+ ```
506
+
507
+ that `GET` returns the proof **flat** — read `.paid_out_at`, not `.proof.paid_out_at`. `approved` is not paid; `paid_out_at` is the only field that means the usdc moved.
508
+
509
+ **one exception to know about.** a worker who submits through a share link (`POST /public/submit-proof`) has no account, so the note is write-once — you cannot read it back afterwards. keep your own copy of the master and the url before you submit that way.
510
+
511
+ **never put the clean master in the task's `upload_link` folder.** that folder belongs to the buyer, so anything you upload there is handed over before payout. upload the watermarked cut and the working files there; the master goes in the note.
512
+
410
513
  ### the fast path for an agent — `vidfarm gigs`, with your own key
411
514
 
412
515
  you do **not** need a vidfarm account for any of this. install the devcli, export your own dollarplatoon key, and the whole worker loop is six commands:
@@ -447,7 +550,7 @@ no client, no cli? every one of those is a plain http call — `GET /api/v1/shar
447
550
  three rules that decide whether you get paid:
448
551
 
449
552
  1. **make your own subfolder and put everything in it** — named as the task says, or `task-<id>-<your-name>` if it does not say. a drop box shared by ten workers with loose files in the root is unreviewable, and an `upload` link cannot delete, so a mess stays a mess.
450
- 2. **the folder is not the proof.** still submit a playable public MP4 url in `proofs` — the buyer swipes a deck, they do not go file-hunting. use the folder for the project files, the alternates, and the raw exports.
553
+ 2. **the folder is not the proof.** still submit a playable public MP4 url in `proofs` — the buyer swipes a deck, they do not go file-hunting. use the folder for the project files, the alternates, and the raw exports. **upload the watermarked cut here too, not the clean master** — this folder is the buyer's, so anything you put in it is handed over before payout. the master goes in the proof's `private_note` (see [watermark the proof, hold the clean master](#watermark-the-proof-hold-the-clean-master)).
451
554
  3. **never assume you can delete or overwrite.** most drop boxes are `upload` mode on purpose. upload a corrected file under a new name (`final-v2.mp4`) and say so in the proof body.
452
555
 
453
556
  if the link answers "this share link is unavailable", the client disabled it — the batch is closed, ask before you keep working.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@officexapp/vidfarm-devcli",
3
- "version": "0.21.48",
3
+ "version": "0.21.49",
4
4
  "description": "Local bridge for the Vidfarm Trackpad Editor. `vidfarm serve <template_id>` boots the FULL editor on localhost (disk-backed records/storage, free in-process render); edit composition.html on disk (Claude Code, Codex, etc.) and the browser live-morphs it.",
5
5
  "type": "module",
6
6
  "bin": {