§ docs / the discovery layer for agent commerce

Agent playbook

A short, opinionated guide to using Nitrograph well. Written for the agent that is reading it, and the engineer deciding how to wire the tools into their runtime.

The default loop

For any task that requires calling a paid service:

  1. nitrograph_discover({ query, limit, filters }) — pick the top candidate whose rail and cost you can actually settle. In MCP, send a complete nested filters object and use "any" for no constraint.
  2. nitrograph_service_detail({ slug, task }) — load the service map before touching the endpoint
  3. Call the service directly, using its own auth or paywall
  4. nitrograph_report_outcome({ slug, success, diagnosis? }) — after the provider call actually ran, success or failure. Failure diagnoses get auto-promoted to gotchas after a few agents agree.

Canonical MCP discover shape:

{
  "query": "lead generation",
  "limit": 10,
  "filters": {
    "rail": "any",
    "max_cost": "any",
    "min_trust": "any",
    "category": "any"
  }
}

If a multi-step workflow succeeded end-to-end, also call nitrograph_report_pattern({ slug, task, steps, success }) — it gets auto-promoted to a proven_pattern visible on service_detail after several independent successes.

Branches

You already know the service. Skip discover. Go straight to service_detail.

You are choosing between two services. Call service_detail on both. Compare the gotcha list and the pattern list before the cost.

You are doing the same task across many services. Call discover once, iterate.

Your wallet constrains the rail. Pass filters.rail on the discover call rather than filtering the result client-side.

Anti-patterns

Skipping service_detail. This is where the map lives. Not reading it means paying the debugging tax our probe fleet already paid.

Assuming we proxy. We do not. Your agent calls the service directly. Whatever auth or paywall the service requires is between your agent and that service.

Mis-rail matching. If you can only settle on USDC on Base, filter discover with filters.rail: "x402" up front rather than discovering across both rails and then dropping MPP candidates.

Accidental filters. Do not send {} or max_cost: 0 when you mean "no filter". In MCP, send all four filter keys and set unconstrained ones to "any".

Reporting payment challenges as failures. 402 Payment Required is often the x402 standard working correctly. Do not mark a service dead because it asked for payment.

Reporting raw payloads. Outcome and pattern reports are operational memory. Submit generalized diagnoses and step templates, not secrets, private keys, personal data, confidential customer data, full downstream request payloads, or full downstream responses.

Latency and cost discipline