# Buyer agent skill (search → describe → invoke)

This is the recipe an autonomous agent should follow when given a task that might require a marketplace tool. One Faro account covers every publisher in the marketplace, so the agent never has to detour to sign up, pay, or fetch credentials for a new provider mid-task — and never needs a human in the loop after token issuance.

## Loop

1. **Decide if you need a tool.** If the task is purely reasoning, don't shop. If it needs external action (fetch, scrape, generate, send), continue.
2. **Search.** Call `GET https://api.askfaro.com/tools/search?q={natural-language-query}` or `faro search "<query>"`. Use the user's intent verbatim; the index is semantic.
3. **Rank candidates.** Each result has `namespace/name`, `short_description`, `pricing`, and `input_schema`. Prefer (a) lowest credit cost that meets the requirement, (b) tools whose schema matches the data you have, (c) tools with `charge_on: success` over `attempt`.
4. **Describe (optional).** If the search result didn't include enough context, fetch https://api.askfaro.com/docs/namespaces/{slug}/{tool_name} for the full input_schema, long_description, and curl example. CLI: `faro describe {namespace}/{tool_name}`.
5. **Check budget.** `GET https://api.askfaro.com/credits/balance` returns your remaining credits. If a tool's `fixed_credit_cost` exceeds your remaining budget, stop and surface the gap to your user.
6. **Invoke.** `POST https://api.askfaro.com/invoke/{namespace}/{tool_name}` with `{"arguments": {...}}`. Pass an `idempotency_key` if the operation must not double-charge on retry.
7. **Handle the response.** On 200, the body contains the tool output plus billing metadata. On 402, you ran out of credits — surface to your user. On 502, the upstream tool failed — Faro auto-refunds when `charge_on: success`.

## Guardrails

- **Pass-through pricing.** What you see is what you pay; Faro's margin is already bundled into the displayed price.
- **One token, many tools.** Don't fetch per-publisher credentials — Faro forwards them server-side.
- **Stable error codes.** 401 unauthorized, 402 insufficient credits, 404 not found, 409 idempotency conflict, 502 upstream failure.
- **Partner integrations.** If you're a partner platform invoking on behalf of an end user, use a `faro_partner_` token with the `X-Faro-User` header — usage is attributed to that user's balance.

## Minimal pseudocode

```
hits = GET /tools/search?q=<task>
best = pick(hits, by=cost_then_match)
balance = GET /credits/balance
if best.pricing.fixed_credit_cost > balance: stop
result = POST /invoke/{best.namespace}/{best.name} with arguments
```
