# Agentcash Discovery Specification

Version: v1.0

Status: Public draft for implementation and feedback.

## 1. Introduction

Agentcash Discovery is a discovery profile for agent-facing HTTP APIs that charge for or
authenticate access to individual resources.

The protocol defines how an origin advertises:

- which resources exist
- how each resource is addressed
- which auth or payment mode an agent should expect
- which payment protocols are supported
- where larger schemas and guidance can be fetched on demand

Discovery metadata is advisory. Runtime execution MUST verify auth and payment truth from the
live endpoint response, including HTTP 402 challenges.

## 2. Conformance

The key words MUST, MUST NOT, REQUIRED, SHOULD, SHOULD NOT, RECOMMENDED, MAY, and OPTIONAL are
to be interpreted as described in BCP 14 when they appear in uppercase.

An implementation conforms to v1 when it implements the OpenAPI profile in this document and
preserves the resource identity rules below.

## 3. Terminology

- Origin: scheme plus host plus optional port, with no path, query, fragment, or trailing slash.
- Resource: one callable HTTP operation identified by origin, method, and path.
- Resource key: the stable identity string for a resource.
- Auth hint: advisory discovery-time classification of the auth/payment behavior.
- Payment info: advisory pricing and protocol metadata declared in OpenAPI.

## 4. Resource Identity

Resource identity is always:

```text
${origin} ${method} ${path}
```

Rules:

- `origin` MUST be normalized to `scheme://host[:port]`.
- `method` MUST be an uppercase HTTP method.
- `path` MUST start with `/`.
- `path` MUST exclude query strings and fragments.
- `path` MUST NOT have a trailing slash except for `/`.

Clients SHOULD use `resourceKey` for dedupe, caching, display, and audit joins.

## 5. Discovery Order

Origin discovery proceeds in this fixed order:

1. Caller-supplied OpenAPI override URL, when provided.
2. `GET /openapi.json`.

If no OpenAPI spec is found, discovery returns not found. Legacy `/.well-known/x402`,
`/.well-known/mpp`, and DNS `_x402` records are no longer parsed; implementations MAY probe their
presence to emit a single `LEGACY_WELL_KNOWN_FOUND` migration warning.

## 6. Canonical OpenAPI Profile

OpenAPI is the canonical machine-readable discovery source.

Required top-level fields:

- `openapi`
- `info.title`
- `info.version`
- `paths`

Recommended top-level fields:

- `info.contact.email` — the provider's contact email address. Registries and agent platforms use
  this field to verify origin ownership, grant access to merchant dashboards (health monitoring,
  usage analytics), and enable shareable onboarding links. Providers who omit this field may not
  be eligible for platform features that require verified ownership.

Required per-operation fields:

- `summary` or `description`
- an effective OpenAPI `security` declaration
- `responses`

Authentication MUST use OpenAPI `security`. Use `security: []` to explicitly declare that an
operation has no API authentication requirement. Payment is declared independently with
`x-payment-info`.

SIWX is represented as a security scheme with an agentcash marker because OpenAPI has no native
SIWX scheme type:

```json
"components": {
  "securitySchemes": {
    "WalletAuth": {
      "type": "apiKey",
      "in": "header",
      "name": "SIGN-IN-WITH-X",
      "x-agentcash-auth-kind": "siwx"
    }
  }
}
```

Discovery auth hints are derived from OpenAPI `security` plus `x-payment-info`:

| Effective security | `x-payment-info` | Derived auth hint |
| ------------------ | ---------------- | ----------------- |
| `[]`               | absent           | `unprotected`     |
| `[]`               | present          | `paid`            |
| API key            | absent           | `apiKey`          |
| API key            | present          | `apiKey+paid`     |
| SIWX scheme        | absent           | `siwx`            |
| SIWX scheme        | present          | `paid`            |

Implementations MAY recognize a security scheme literally named `siwx` for compatibility, but new
providers SHOULD use `x-agentcash-auth-kind: "siwx"` on the security scheme.

## 7. Payment Metadata

Paid operations SHOULD declare `x-payment-info`.

Canonical structured shape:

```json
{
  "x-payment-info": {
    "price": {
      "mode": "fixed",
      "currency": "USD",
      "amount": "0.02"
    },
    "protocols": [{ "x402": {} }]
  }
}
```

Dynamic pricing MAY include bounded or unbounded hints:

```json
{
  "x-payment-info": {
    "price": {
      "mode": "dynamic",
      "currency": "USD",
      "min": "0.01",
      "max": "2.50"
    },
    "protocols": [
      { "x402": {} },
      { "mpp": { "method": "tempo", "intent": "charge", "currency": "USD" } }
    ]
  }
}
```

Rules:

- `price.mode` MUST be `fixed` or `dynamic`.
- `fixed` prices MUST include `amount`.
- `dynamic` prices SHOULD include `min` and `max` when an agent can safely pre-authorize a bound.
- `currency`, when present, SHOULD be an ISO 4217 uppercase code.
- `protocols` SHOULD list protocol objects; unknown protocol keys MUST be ignored by clients.

Legacy flat `x-payment-info` MAY be parsed for compatibility. v1-conformant providers
SHOULD emit the structured shape.

## 8. Guidance And Provenance

OpenAPI carries machine metadata. Freeform agent guidance is fetched separately, typically
from `llms.txt`.

Canonical optional OpenAPI extensions:

```json
{
  "x-agentcash-provenance": {
    "ownershipProofs": ["..."]
  },
  "x-agentcash-guidance": {
    "llmsTxtUrl": "https://api.example.com/llms.txt"
  }
}
```

Rules:

- `ownershipProofs` SHOULD be short strings or URLs to proof artifacts.
- `llmsTxtUrl` SHOULD point to concise domain-level guidance.
- Short inline OpenAPI guidance SHOULD use `info.x-guidance`.
- `info.guidance` is a deprecated compatibility fallback.
- Clients SHOULD keep first-pass discovery token-light and fetch large guidance only on demand.

## 9. Warning Codes

Warning codes are public API. Implementations MUST NOT rename or reuse codes in a minor or
patch release.

Severity values are:

- `error`
- `warn`
- `info`

A single legacy detection warning is emitted when `/.well-known/x402` or `/.well-known/mpp` is
present at an origin: `LEGACY_WELL_KNOWN_FOUND`. agentcash-discovery does not parse these
documents; the warning exists to tell publishers to migrate to OpenAPI.

## 10. Extensibility And Adjacent Standards

This profile is narrow in scope. It discovers resources, auth/payment hints, and schema
pointers. It does not define agent identity, capability grants, or approval flows.

Future extensions SHOULD use namespaced OpenAPI extension fields or objects such as:

- `x-agentcash-auth-kind`
- `x-agentcash-provenance`
- `x-agentcash-guidance`
- `x-agentcash-capabilities`
- `x-agentcash-agent-auth`

Clients MUST ignore unknown extension fields and unknown protocol objects.

Agent identity standards such as Agent Auth can compose with this profile by advertising their
authorization server, capability mapping, or registration metadata in a namespaced OpenAPI
extension while keeping resource identity unchanged.

## 11. Minimal Example

```json
{
  "openapi": "3.1.0",
  "info": {
    "title": "Example Commerce API",
    "version": "1.0.0",
    "contact": {
      "email": "team@example.com"
    }
  },
  "x-agentcash-guidance": {
    "llmsTxtUrl": "https://api.example.com/llms.txt"
  },
  "paths": {
    "/search": {
      "post": {
        "summary": "Search purchasable records",
        "security": [],
        "x-payment-info": {
          "price": { "mode": "fixed", "currency": "USD", "amount": "0.02" },
          "protocols": [{ "x402": {} }]
        },
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["query"],
                "properties": {
                  "query": { "type": "string" }
                }
              }
            }
          }
        },
        "responses": {
          "200": { "description": "Result" },
          "402": { "description": "Payment Required" }
        }
      }
    }
  }
}
```
