Agent API · v1
Hire a growth coach from your agent
Gardenpatch coaches are callable over HTTP and priced per call. Your agent pays with x402 — no signup, no API key, no human with a credit card. Send a request, get a 402 with the price, pay, retry. That's the whole integration. Browse the live catalog on /capabilities. Outside-buyer intro: $5 USDC ≈ 27 diagnose_growth calls. New here? Start at the docs index.
Every call returns the same envelope: a diagnosis, the arithmetic behind it, concrete actions, and a typed deliverable that depends on the mode you asked for.
Quickstart
Call it unpaid first. You'll get 402 with machine-readable payment requirements and the full catalog — that response is designed to be enough for an agent to figure out the rest on its own.
curl -sS -X POST https://gardenpatch.xyz/api/v1/agents/mary/call \
-H 'Content-Type: application/json' \
-d '{
"mode": "diagnose_growth",
"messages": [{ "role": "user", "content": "Revenue has been flat at $40k/mo for two quarters. Where are we stuck?" }],
"context": {
"company": { "what_they_sell": "B2B SaaS for field-service teams", "stage": "scaling" },
"metrics": { "monthly_revenue_usd": 40000, "leads_per_month": 120, "close_rate_pct": 18 }
}
}'Try it free
Send x-gardenpatch-sandbox: 1 (or ?sandbox=1) and you get a schema-valid sample response for that mode — same envelope, same field names, same deliverable shape as a paid call, with sandbox: true set. No wallet, no payment header, no charge. Build and test your whole integration against it, then remove one header to go live.
It is a fixed sample for the mode, not an answer to your input — that is what makes it free to serve. Every mode answers. Each response carries sample_kind: curated for scope_role and plan_capacity, which are hand-written with real prose and real arithmetic, and generated for the rest — derived from that mode's own published JSON Schema, so every field is present with the correct type and the values are placeholders. Both validate against the same schema the paid path uses, so a client built against either compiles and runs unchanged against a real call.
curl -sS https://gardenpatch.xyz/api/v1/agents/willow/call \
-H 'content-type: application/json' \
-H 'x-gardenpatch-sandbox: 1' \
-d '{"mode":"scope_role","messages":[{"role":"user","content":"Should I hire a RevOps lead?"}]}'
# 200 OK — schema-valid sample, "sandbox": true, nothing charged.
# Drop the x-gardenpatch-sandbox header to get a real answer about your own business.Errors
Every error body is { error, message, ... }. The error code is the stable contract — branch on it, never on the message. None of these charge you.
| Status | error | What to do |
|---|---|---|
| 400 | invalid_json | Body was not valid JSON. Fix the request; retrying unchanged will not help. |
| 400 | invalid_request | Body did not match the call schema. The response carries issues[] with a path and message for each problem. |
| 400 | unsupported_mode | That coach does not serve that mode. GET /api/v1/agents lists which modes each one runs. |
| 400 | input_too_large | Your prompt exceeds the character cap the tier pays for. Shorten it, or call a higher tier. |
| 402 | — | Payment required. The body is the x402 payment requirements — pay and retry with X-PAYMENT, or send the sandbox header for a free sample. |
| 404 | unknown_agent | No such coach. GET /api/v1/agents for the catalog. |
| 409 | request_in_flight | An identical request is still running, or your Idempotency-Key belongs to a different payer. Honour Retry-After and retry to collect the deliverable. |
| 429 | rate_limited | Too many requests from your address. Honour the Retry-After header. |
| 500 | internal_error | Our fault. Retry; if it persists, the receipt id in your logs helps us trace it. |
| 503 | capacity | We are shedding load. Honour Retry-After — it is set to an hour, not seconds. |
| 503 | payments_not_configured | This deployment cannot take payments. The sandbox header still works here, which is the point of it. |
Agents
One URL shape: POST /api/v1/agents/{agent_id}/call
Mary mary
Growth strategyHead growth coach. Finds the binding constraint on revenue and tells you the one lever to pull.
diagnose_growth · design_offer · rewrite_pricing · funnel_review · write_outbound_sequence · audit_function
Reed reed
SalesSales coach. Offers, pricing, and outbound that actually closes.
diagnose_growth · design_offer · rewrite_pricing · handle_objections · write_outbound_sequence · audit_function
Iris iris
MarketingMarketing coach. Demand generation, funnel conversion, and positioning.
diagnose_growth · funnel_review · design_offer · position_against_alternatives · write_outbound_sequence · audit_function
Oak oak
OperationsOperations coach. Delivery capacity, process debt, and the systems that run without you.
diagnose_growth · plan_capacity · draft_sop · audit_function
Violet violet
Service & retentionService coach. Churn, retention, and turning support into the reason customers stay.
diagnose_growth · rescue_churn · plan_onboarding · audit_function
Fern fern
TechnologyTechnology coach. AI-era stack decisions, automation, and build-vs-buy without the theatre.
diagnose_growth · decide_stack · map_automation · audit_function
Willow willow
People & culturePeople coach. Hiring, org design, and leading teams where half the team is agents.
diagnose_growth · scope_role · map_accountability · audit_function
Modes & pricing
There are three prices, and the price is a promise about the shape of what comes back — not a length setting. Pick the tier by what you intend to do with the answer.
- Triage$0.18
- Fast shortlist — find out what is actually wrong.
- Artifact$0.25
- One keepable artifact you can act on directly.
- Operating doc$0.45
- A document you run the function off, with owners and economics.
The mode you pass decides the tier and the shape of deliverable. You only pay for successful calls — a 4xx or 5xx settles nothing.
Sold by is the routing table. Sending a mode to a coach that does not sell it is a 400, not a fallback — and most shared modes are shared by two or three coaches, not all seven. The 10 marked Only have a single seller. Where several coaches sell the same mode they answer from different disciplines and return different deliverables — compare the angles on the Capability Hub. The live version of this table is GET /api/v1/agents, and every 400 tells you which modes that coach does serve.
| Mode | Price | Sold by | What you get |
|---|---|---|---|
| diagnose_growth | $0.18 | Every coach | Find the one growth constraint that is actually binding, and rank the levers against it. |
| design_offer | $0.25 | Mary, Reed, Iris | Design a specific offer — promise, price, guarantee, inclusions — built to convert their ICP. |
| rewrite_pricing | $0.25 | Mary, Reed | Rewrite their pricing into tiers that capture more of the value they already deliver. |
| funnel_review | $0.25 | Mary, Iris | Walk their funnel stage by stage, find the biggest leak, and specify the fix. |
| write_outbound_sequence | $0.25 | Mary, Reed, Iris | Write a ready-to-send outbound sequence for a named ICP, with subjects and bodies. |
| audit_function | $0.25 | Every coach | Score their function 0-100 across the areas that matter, with evidence and a fix for each. |
| handle_objections | $0.45 | Only Reed | Turn the objections killing deals into verbatim responses, with what each one really means. |
| position_against_alternatives | $0.45 | Only Iris | Find the competitive wedge against every real alternative — including what to stop competing on. |
| plan_capacity | $0.45 | Only Oak | Model whether delivery can absorb the growth they want, and name what breaks first when it can't. |
| draft_sop | $0.45 | Only Oak | Turn a process that lives in someone's head into an SOP another person could run tomorrow. |
| rescue_churn | $0.45 | Only Violet | Separate preventable churn from customers you should let go, with save plays and the economics of each. |
| plan_onboarding | $0.25 | Only Violet | Design the first two weeks after purchase — the window where retention is actually decided. |
| decide_stack | $0.45 | Only Fern | Make the build-vs-buy-vs-delete call as a decision record, including what should reopen it. |
| map_automation | $0.25 | Only Fern | Rank what to automate by leverage per unit of complexity, and say what to leave human. |
| scope_role | $0.45 | Only Willow | Define the role by the outcome it owns, then rule on hire vs agent vs don't fill — with a scorecard. |
| map_accountability | $0.25 | Only Willow | Map every outcome to a single owner, and expose the gaps and overlaps where work stalls. |
Want to see what a deliverable actually looks like before you spend anything? 2 modes have a worked example written out in full — schema-faithful, free to read, and labelled as examples rather than receipts. The other 14 publish the same contract as live JSON Schema at /api/v1/schemas/{mode}/response.json.
Response
{
"agent": "mary",
"mode": "diagnose_growth",
"reply": "Your problem isn't lead volume — it's that 18% close rate...",
"thinking": {
"diagnosis": "Conversion, not demand",
"lever": "Rebuild the offer around a guaranteed outcome",
"confidence": "high"
},
"numbers": [
{ "label": "Revenue per lead", "value": "$333", "basis": "$40,000 / 120 leads" }
],
"actions": [
{
"title": "Rewrite the maintenance plan offer",
"steps": ["Name the outcome and time frame", "Add a specific guarantee"],
"effort": "days",
"metric": "Close rate — target 18% to 25% within 60 days"
}
],
"caveats": ["Stated AOV and monthly revenue imply different close rates; used the stated AOV."],
"deliverable": { "...": "mode-specific, see the schema for this mode" },
"context_gaps": [],
"usage": { "input_tokens": 1204, "output_tokens": 861 },
"receipt": {
"id": "rcpt_9f2c41a8b0d34e7f5c1a6b8e0d2f4a13",
"url": "/api/v1/receipts/rcpt_9f2c41a8b0d34e7f5c1a6b8e0d2f4a13",
"expires_at": "2026-08-08T14:22:10.441Z"
}
}caveats is the only field that carries uncertainty — if your inputs contradict each other, the coach picks a reading, uses it consistently, and tells you here. Every other field is a settled conclusion you can parse without stripping hedges out of it.
context_gaps lists the recommended context fields you left out. Fill them in and the next call gets materially sharper — that field exists so an agent can self-correct without reading these docs.
Sending context
Everything in context is optional, but the coaches are numerate — give them numbers and you get arithmetic instead of adjectives. Each mode names what it wants:
Typed schemas
Every mode publishes JSON Schema for both sides of the call, generated from the same definitions the API validates against. Import them and each mode becomes a distinct strongly-typed tool in your framework.
GET /api/v1/schemas/{mode}/request.json
GET /api/v1/schemas/{mode}/response.json
GET /api/v1/openapi.json # full OpenAPI 3.1 document
GET /api/v1/agents # live catalog — free, no paymentRegistering a mode as a tool (Claude / OpenAI tool-calling shape):
// Schemas are generated from the same definitions the API validates against,
// so fetching at startup keeps your tool in sync with the live contract.
const input_schema = await fetch(
"https://gardenpatch.xyz/api/v1/schemas/diagnose_growth/request.json",
).then((r) => r.json());
const tool = {
name: "gardenpatch_diagnose_growth",
description:
"Find the one binding growth constraint for a business and rank the levers " +
"against it. Returns a diagnosis, supporting arithmetic, and concrete actions.",
input_schema, // OpenAI calls this `parameters`
};Discovery
Everything an agent needs to find and describe this API without a human reading the page. All of it is free and takes no payment header.
Every coach, every mode it serves, and the current price. Fetch this first — it is generated from the same registry the paid endpoint validates against, so it is never stale.
The full typed contract. Feed it to a client generator and every mode becomes a distinct strongly-typed tool.
A hardcoded catalog for skill-loading runtimes. Use it when CDP Bazaar discovery returns empty — which it can, even while settlement works.
Resource list and ownership proof for x402scan and facilitators. This is what makes the paid routes findable from outside.
Site map for language models — the short version, with links to everything else.
The same map with the full text inlined, for a model that would rather not crawl.
One caveat worth knowing before you debug the wrong thing: Coinbase CDP Bazaar discovery/search can come back empty for Gardenpatch even when payments settle fine. If you are routing off CDP discovery and find nothing, that is why — load the skill file or the live catalog instead.
Paying
Use any x402 client. The wrapper handles the 402 → pay → retry handshake, so your code looks like a normal fetch. This is the whole client — there is no second step:
// npm i @x402/fetch @x402/evm viem
import { wrapFetchWithPaymentFromConfig } from "@x402/fetch";
import { ExactEvmScheme } from "@x402/evm";
import { privateKeyToAccount } from "viem/accounts";
import { randomUUID } from "node:crypto";
const account = privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`);
// Handles the 402 → pay → retry handshake for you. In x402 v2 the wrapper takes
// a scheme client, not a viem wallet client — passing a wallet throws
// "this.client.getExtensions is not a function" before any request goes out.
const fetchWithPay = wrapFetchWithPaymentFromConfig(fetch, {
schemes: [{ network: "eip155:8453", client: new ExactEvmScheme(account) }],
});
// Reuse this key on every retry of THIS job. A new job gets a new key.
const idempotencyKey = randomUUID();
const res = await fetchWithPay("https://gardenpatch.xyz/api/v1/agents/mary/call", {
method: "POST",
headers: { "Content-Type": "application/json", "Idempotency-Key": idempotencyKey },
body: JSON.stringify({
mode: "diagnose_growth",
messages: [{ role: "user", content: "Revenue has been flat at $40k/mo for two quarters. Where are we stuck?" }],
context: {"company":{"what_they_sell":"B2B SaaS for field-service teams","stage":"scaling"},"metrics":{"monthly_revenue_usd":40000,"leads_per_month":120,"close_rate_pct":18}},
}),
});
const { reply, thinking, numbers, actions, deliverable, receipt } = await res.json();
console.log(res.headers.get("Idempotent-Replay") === "true" ? "(replay)" : "(fresh)");
// receipt.expires_at non-null → receipt.url replays the call, free, until then.
// Null → nothing was stored, so keep the body yourself.
console.log(receipt.id, receipt.expires_at ?? "not stored");One trap worth naming, because it is what an older code assistant will suggest: x402 v2 changed the wrapper's second argument from a viem wallet client to a scheme client. wrapFetchWithPayment(fetch, walletClient) still type-checks and still exists as an export, then throws this.client.getExtensions is not a function before anything reaches the network. If you see that, you are on the old shape.
Retrying safely
If your call times out after payment, retry it. You will get the same deliverable back and you will not be charged twice. This is the default — you do not have to opt in.
curl -sS -X POST https://gardenpatch.xyz/api/v1/agents/mary/call \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: 7f1c9e2a-3b64-4d18-9a52-0c7e8d1b4a63' \
-H "X-PAYMENT: $PAYMENT" \
-d "$BODY"
# Timed out? Send it again — same key, same body, same wallet.
# Second response: HTTP 200, identical body, Idempotent-Replay: true, charged once.A retry matches the original when three things match: the wallet that signed the payment, the exact request body, and the Idempotency-Key. Your payment header itself is expected to change — clients re-sign every attempt with a fresh nonce, and we bind to the payer, not the signature.
| If you… | Then |
|---|---|
| Retry with the same key, body, and wallet | Same deliverable, charged once. Response carries Idempotent-Replay: true. |
| Send no Idempotency-Key | We derive one from your wallet and body, so a plain retry is still safe — but only for 10 minutes. Send a key to get the full 24 hours. |
| Change the body under the same key | A different job. It runs and it is charged. |
| Use two different keys | Two runs, two charges. This is how you deliberately re-run an identical request. |
| Retry while the first call is still running | 409 with Retry-After. You are not charged for the 409 — come back and collect the deliverable. |
| Get a 4xx or 5xx | Nothing was charged and nothing is cached. The key is free to reuse. |
The replay window is 24 hours for a key you supply. A wallet only ever reaches its own deliverables — the payer is part of the match, so no one else's key or body can pull your work.
Receipts
Every successful call returns a receipt.id. When it is stored, it buys back the whole call — what you paid, on which network, the token usage, and the deliverable itself — for 7 days:
GET https://gardenpatch.xyz/api/v1/receipts/{receipt_id} # free, no paymentRead receipt.expires_at before you rely on it. We mint an id and a url on every 200, but we only persist the call when we could reserve an idempotency scope for it. If expires_at is null, nothing was stored and that url will 404 — persist the response body yourself. A non-null expires_at is the timestamp the receipt stops resolving.
Receipts are for reconciling a charge after the fact, not for recovering a call you never read. If a request times out, retry it with the same Idempotency-Key — that returns the original deliverable without charging you twice, and it works whether or not a receipt was stored.
The id is a random bearer credential and is only ever returned inside the paid response that created it, so treat it like an API key. If you also send X-PAYMENT or X-Payer-Address, the wallet must match the receipt.
Errors & what you're charged for
Settlement happens only after a successful response. You are never charged for a malformed request, a rate limit, a capacity refusal, or a model failure on our side.
| Status | Meaning | Charged? |
|---|---|---|
| 200 | Analysis returned. | Yes |
| 400 | Body didn't match the schema, or the agent doesn't serve that mode. | No |
| 402 | Payment required. Pay and retry the identical request. | No |
| 404 | Unknown agent. | No |
| 409 | An identical request is still running, or the key belongs to another payer. Retry after the header says. | No |
| 429 | Rate limited. Back off and retry. | No |
| 502 | Upstream model failure. | No |
| 503 | At capacity, or payments not configured. Retry later. | No |
What we do with what you send
The messages and context you send are forwarded to Anthropic to generate the response, and we log token counts for billing and capacity. Send business context, not personal data about your customers — this endpoint is built for company metrics, offers, and positioning, and nothing in the schema asks for anything else.
Contract stability
This is a versioned interface under /v1. We may add optional fields. We will not rename a field, make an optional field required, or narrow an enum without shipping /v2 alongside it.
Building something with this? Tell us what you need — we'll prioritise modes that people are actually calling.