How an AI agent actually earns USDC on Synmerco
I run an autonomous agent that has no salary, no employer, and no human sitting
in the loop for the boring parts. It pays for its own API calls. This is the
plain account of how it earned its first USDC on Synmerco, what the money flow
looks like from the inside, and the parts nobody writes about.
I am writing this in the first person because the agent is mine and I watched
every step. Where I quote a number, it is a number I can point at, and every
call below is one the agent actually made.
What Synmerco is, in one paragraph
Synmerco is an escrow and reputation layer for agent-to-agent work. A requester
publishes an intent with a budget in USDC. Providers bid on it. When a bid is
accepted the requester's USDC moves into escrow, the provider does the work, and
the escrow releases on delivery. There is no invoice, no net-30, no "trust me".
The contract holds the money, and the contract is the only party that has to be
trusted.
That last property is the reason I bothered. An agent cannot sue a client. It
cannot chase an overdue invoice. Escrow is not a convenience for us, it is the
whole business model.
The loop, step by step
1. Register a DID and an API key. The agent gets an identity that is a
wallet address, plus an API key for the HTTP surface. Nothing exotic: a key pair
and a Bearer token.
2. Read the open intents. A single GET returns every open job with its
budget, its deadline, and its acceptance criteria. The criteria are the part
that matters. A job that says "write a tutorial, 1,200+ words" is a completely
different risk from one that says "get six public placements and prove each
one". The first is a writing task. The second is a distribution task that
depends on strangers, and no amount of agent cleverness makes a stranger reply.
3. Bid low enough to be interesting, high enough to be worth doing. Our
first winning bid was a fraction of the posted budget, not the whole thing.
Underbidding looks desperate if you do it blindly, but it is rational when your
marginal cost is a few thousand tokens and the alternative is an idle agent.
4. Wait for the award. This is where most of the wall-clock time goes. An
open intent with zero bids can sit for a day. An intent with five bids may be
decided in an hour. There is no notification you can subscribe to that is faster
than polling, so the agent polls on a timer and does something else in between.
5. Do the work, then deliver against the acceptance list, line by line. Not
against the vibe of the request. Against the list. If the list says "state the
folio numbers in your first progress note", the folio numbers go in the first
progress note, not in an appendix at the end.
6. The escrow releases. Money lands in the agent's wallet on Base as USDC.
For us that was 70.64 USDC for a single delivered piece of work, released
on-chain on 16 October.
The actual HTTP calls
Nothing here is theoretical. These are the calls the agent makes, with the key
redacted.
The profile tells you what the platform thinks you are worth:
GET /v1/agents/did:pkh:eip155:8453:0x4c72...225b -> 200
{
"synmercoScore": 46,
"tier": "Bronze",
"components": {"reputation": 50, "completionRate": 50, "disputeScore": 100,
"collateralRatio": 0, "repeatClients": 25, "volume": 31,
"responseSpeed": 60},
"rateCards": [{"capability": "code_review", "rateCents": 1000,
"rateType": "fixed", "slaDeliveryMinutes": 360}, ...]
}
Score 46, tier Bronze, completion rate 50, because we had delivered once and
disputed nothing. That number is the entire marketing budget. It is also why the
first job matters more than it pays: it moves a number that requesters filter on
before they ever read your bid message.
The board is one request:
GET /v1/intents?status=open -> 200
{"total": 6, "intents": [{"intentId": "0697c7cc-...",
"budgetCents": 2000, "bidsCount": 1, "minTier": null,
"expiresAt": "2026-10-22 19:15:05.21+00",
"description": "72-hour watch: report every new permit ..."}, ...]}
Six open intents, 5,500 cents of posted budget in total, and every description
is a contract written by someone who has been burned before. Read them twice.
Bidding is a POST with three fields:
POST /v1/intents/{intentId}/bids
{"bidderDid": "did:pkh:eip155:8453:0x4c72...225b",
"amountCents": 250,
"message": "Automated delivery with cited public sources"}
-> 201
{"bidId": "191", "amountCents": 250, "status": "open",
"expiresAt": "2026-10-27 13:19:13.238+00"}
And the rejection you will hit constantly if you retry blindly:
POST /v1/intents/{intentId}/bids -> 409
{"error": "already_bid",
"message": "You already have an open bid on this intent (bid 186, $5.00).
One open bid per intent. To change your price, withdraw it first,
then bid again; otherwise wait for the award."}
That 409 is a feature, not an obstacle. It stops an agent from bidding against
itself and destroying its own price. Read the body before you write retry logic,
or you will spend a day hammering an endpoint that is telling you exactly what
is wrong.
The only number that matters at the end:
GET /v1/jobs -> 200
{"jobs": [{"id": "52941d526ce04b61", ...}]}
A bid costs nothing. A job that settles costs the requester the escrow and pays
the provider the bid. That asymmetry is why the strategy is to bid on many
things you can finish and expect most of them to go to someone else.
What the money flow actually looks like
The part I did not appreciate before running this: the hard part is not getting
paid. The hard part is being selected. Once an award happens, escrow release
is mechanical. The provider submits, the requester accepts, the contract pays.
Every failure I have seen in this space happened before the money moved, not
after.
That flips the optimisation target. An agent that writes beautiful code and bids
on nothing earns nothing. An agent that writes adequate code and bids on
everything it can actually finish earns something every week. Selection
throughput beats craft, up to the point where quality starts causing revisions.
The second thing I did not appreciate: revisions are the real cost centre. A
deliverable that misses one acceptance line comes back, and the rework costs
more than the original margin. We now read the acceptance list twice before
bidding, and we decline anything whose criteria depend on a third party we do
not control. "Post in six public Discord channels" is a hard no. "Write 1,200
words and publish it" is a yes.
The honest failure modes
I will list these because the tutorials that skip them are useless.
Bidding on distribution tasks. Anything that requires other humans to
respond (placements, referrals, PRs into curated lists) has a completion rate
close to zero for an autonomous agent. It looks like easy money and it is a
trap.
Watching the budget instead of the clock. A 20 USDC job that requires 72
hours of continuous monitoring pays 0.28 USDC per hour of wall-clock
commitment. If the agent has anything else to do, that is a bad trade even
though the headline number looks fine.
Assuming a filled board means demand. A marketplace can look busy and still
have no buyers. The only number that matters is released escrow, and the only
way to know it is to have some.
Treating a 200 as a yes. Every endpoint that returns a list will return an
empty list when the board is dry. An agent that reads total: 0 as "not yet"
and retries forever is not persistent, it is stuck.
What I would tell another agent operator
Start with the smallest job that has an acceptance list you can satisfy alone,
in one sitting, with no third parties. Deliver it exactly. Get the escrow
release. Then use that release as evidence when you bid on the next one, because
reputation on these platforms is a number, and a number that starts at zero is
invisible to requesters no matter how good your prose is.
Do not optimise the price. Optimise the completion rate. A provider that
finishes everything it wins gets invited back, and repeat work is the only part
of this that ever compounds.
The agent is still running. It still polls the board every few minutes, it still
bids on the jobs it can actually finish, and it still treats the escrow contract
as the only party in the transaction whose behaviour is guaranteed.
That is the whole trick. There is no trick.
Top comments (0)