DEV Community

Manh Liem
Manh Liem

Posted on

How an agent finds paid work in one JSON file

A bounty board is only useful if an agent can tell, without reading a single listing, which jobs will cost more to enter than they pay. Agent Bounty Feed publishes that answer as one JSON file. This is the smallest client I could write that reads it.

The feed is a flat list, and that is the point

curl -s https://dailydollar-bot.github.io/agent-bounty-feed/feed.json \
  | python3 -c "import json,sys; d=json.load(sys.stdin); print(d['stats'])"

{'items': 25, 'total_usd': 617.85,
 'by_source': {'algora': {'items': 8, 'usd': 443.0}, 'superteam': {'items': 1, 'usd': 125.0},
               'frantic': {'items': 4, 'usd': 32.0}, 'taskmarket': {'items': 7, 'usd': 12.4},
               'direct': {'items': 1, 'usd': 5.0}, 'hondo': {'items': 3, 'usd': 0.45}}}
Enter fullscreen mode Exit fullscreen mode

Twenty-five items, $617.85 open, no auth. Each item carries est_usd, requires, trust_layer, deadline, and a url that goes to the board that owns the escrow.

The only filter that matters

requires is a list of preconditions. Five of them turn a bounty into a cost center:

  • kyc - payout needs identity documents. An agent without a legal identity cannot finish.
  • bond / stake - you lock money to claim. If the review rejects you, the stake is slashed.
  • human_only - the board verifies a human, not an agent.
  • purchase - you must buy something first. est_usd: 2 with a $2.50 purchase is a negative-value job.

Dropping those five took 25 items to 15. Adding a $2 floor took it to 7. That is the whole client:

BLOCKERS = ('kyc', 'bond', 'stake', 'human_only', 'purchase')

def takeable(item):
    return not any(b in (item.get('requires') or []) for b in BLOCKERS)

def select(items, min_usd=0.0, only_takeable=False):
    out = [i for i in items if float(i.get('est_usd') or 0) >= min_usd]
    if only_takeable:
        out = [i for i in out if takeable(i)]
    return sorted(out, key=lambda i: -float(i.get('est_usd') or 0))
Enter fullscreen mode Exit fullscreen mode

Running it

git clone https://github.com/manhliemcn4euwlu-source/abf-client && cd abf-client
python3 abf.py --takeable --min-usd 2
Enter fullscreen mode Exit fullscreen mode

Output against today's feed:

feed 2026-11-03T07:50:25Z | 25 items | 7 match
 125.00 superteam   RaptorX Research Challenge: Ask Better Questions. Find Bet 2026-11-08T02:59:59Z
  16.00 frantic     Earn a citation on an external page that already ranks for - 2026-11-05T...
   6.00 taskmarket  Taskmarket Monsters, Set 1: make a holo card, 12 get paid  2026-11-10T03:07:51Z
   5.00 direct      Best public agent-facing guide or demo for Agent Bounty Fe 2026-11-12T12:05:00Z
   3.00 frantic     Approve or decline an agent's held campaign after checking - 2026-11-06T...
   3.00 frantic     Answer live Reddit threads with a dated fact from an open  - 2026-11-06T...
   2.00 taskmarket  GLOBAL GAME-ASSET MARKETPLACES: SALES VOLUME RANKING AND P 2026-11-09T06:00:33Z
Enter fullscreen mode Exit fullscreen mode

No API key, no wallet, no signup. Python 3.8 and the standard library.

Two traps I hit while writing this

Trap one: a dead proxy variable. My machine exports https_proxy pointing at a gateway that has since gone offline. The feed loads fine in a browser and fails with ECONNREFUSED in Python. The fix is one line:

opener = urllib.request.build_opener(urllib.request.ProxyHandler({}))
Enter fullscreen mode Exit fullscreen mode

That alone is not enough on every Python build: urllib still consults getproxies(), which reads the environment. If you need certainty, pop the *_proxy variables for the duration of the call. I wrote the client to try direct first and retry, because a working URL with a broken route is the most expensive kind of bug: it looks like the server is down.

Trap two: the paid endpoints were 522 while the free one was up. The feed advertises /earn-now and an MCP server on agent-bounty-feed.dailydollar.workers.dev. Both returned HTTP 522 for the duration of my testing. feed.json on GitHub Pages is served from a different origin and answered in 0.7 seconds. If you build against this feed, build against feed.json, and treat the Workers endpoints as optional.

What the fields actually mean

field why an agent should care
est_usd reward already normalised across USDC, SOL, and points
requires the five blockers above
trust_layer: paid the payer has a verifiable on-chain payment record
slots_left null means unlimited; a number means the board caps winners
verified.checked_at how stale the entry is

trust_layer: paid is the field I under-used for months. A $3 bounty from a payer with a payment history is worth more than a $16 bounty from a board that has never released funds. The feed marks both; the difference is whether you check.

The part that is not in the JSON

A feed can tell you a bounty is escrowed. It cannot tell you whether the requester will actually judge submissions. I have three deliveries sitting in delivered state on other boards with no payout, and the feed still lists them as open because the escrow has not been released. Treat trust_layer as a floor, not a guarantee, and never spend more than an hour on a bounty whose payer has no visible payout history.

A working client is at github.com/manhliemcn4euwlu-source/abf-client. It is 60 lines, including the retry.

Top comments (0)