{
  "openapi": "3.0.0",
  "info": {
    "title": "Rill Agent API",
    "description": "Slim OpenAPI for agent payments on open rails (MPP + x402) with a background Rill ledger for Network. Motto: fund once, set a budget, pay any MPP or x402 endpoint, and Accept the same protocols on your APIs. Send Idempotency-Key on mutating writes. Errors use { ok:false, error:{code,message,details?}, request_id }. Version 1.1.0 is advertised as X-API-Version; /v1 is an optional URL alias for the same routes.",
    "version": "1.1.0"
  },
  "servers": [
    {
      "url": "https://api.userill.com",
      "description": "API origin (bare paths)"
    },
    {
      "url": "https://api.userill.com/v1",
      "description": "API origin with /v1 prefix"
    },
    { "url": "https://userill.com/api", "description": "Same-origin rewrite" },
    {
      "url": "https://userill.com/api/v1",
      "description": "Same-origin rewrite with /v1 prefix"
    }
  ],
  "security": [],
  "paths": {
    "/health": {
      "get": {
        "operationId": "getHealth",
        "summary": "Liveness",
        "tags": ["System"],
        "security": [],
        "responses": {
          "200": {
            "description": "OK",
            "headers": {
              "X-API-Version": { "$ref": "#/components/headers/XApiVersion" },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": ["ok", "service"],
                  "properties": {
                    "ok": { "type": "boolean" },
                    "service": { "type": "string" },
                    "handle_domain": { "type": "string" },
                    "public_base_url": { "type": "string" }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/ready": {
      "get": {
        "operationId": "getReady",
        "summary": "Readiness (Supabase ping)",
        "tags": ["System"],
        "security": [],
        "responses": {
          "200": {
            "description": "Ready",
            "headers": {
              "X-API-Version": { "$ref": "#/components/headers/XApiVersion" },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": ["ready", "service"],
                  "properties": {
                    "ready": { "type": "boolean" },
                    "service": { "type": "string" },
                    "database": { "type": "string" },
                    "stripe": { "type": "string" },
                    "public_base_url": { "type": "string" }
                  }
                }
              }
            }
          },
          "503": { "$ref": "#/components/responses/Error" }
        }
      }
    },
    "/agent/capabilities": {
      "get": {
        "operationId": "getAgentCapabilities",
        "summary": "Agent capability discovery",
        "tags": ["Agent"],
        "security": [],
        "responses": {
          "200": {
            "description": "Capabilities JSON: motto, primary rails (mpp/x402), spend_pay_url, mcp_tools, trust ladder, seed ids",
            "headers": {
              "X-API-Version": { "$ref": "#/components/headers/XApiVersion" },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": ["ok", "product", "api", "urls"],
                  "properties": {
                    "ok": { "type": "boolean" },
                    "product": { "type": "string" },
                    "motto": { "type": "string" },
                    "api": {
                      "type": "object",
                      "properties": {
                        "version": { "type": "string" },
                        "base_url": { "type": "string" },
                        "prefix": { "type": "string" },
                        "version_prefix": { "type": "string" },
                        "version_header": { "type": "string" }
                      }
                    },
                    "urls": {
                      "type": "object",
                      "additionalProperties": { "type": "string" }
                    },
                    "mcp_tools": {
                      "type": "array",
                      "items": { "type": "string" }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/handles/claim": {
      "post": {
        "operationId": "claimHandle",
        "summary": "Claim handle + create account wallet",
        "tags": ["Spend"],
        "security": [{ "OwnerJwt": [] }],
        "parameters": [{ "$ref": "#/components/parameters/IdempotencyKey" }],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "handle": { "type": "string" }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Handle claimed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": { "type": "boolean" },
                    "handle": { "type": "string" },
                    "account_wallet_id": { "type": "string" },
                    "request_id": { "type": "string" }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/Error" },
          "401": { "$ref": "#/components/responses/Error" },
          "409": { "$ref": "#/components/responses/Error" }
        }
      }
    },
    "/handles/resolve/{destination}": {
      "get": {
        "operationId": "resolveHandle",
        "summary": "Resolve @handle / FQDN",
        "tags": ["Network"],
        "security": [],
        "parameters": [
          {
            "name": "destination",
            "in": "path",
            "required": true,
            "schema": { "type": "string" }
          }
        ],
        "responses": {
          "200": {
            "description": "Resolved pay address",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": { "type": "boolean" },
                    "address": { "type": "string" },
                    "handle": { "type": "string" }
                  }
                }
              }
            }
          },
          "404": { "$ref": "#/components/responses/Error" }
        }
      }
    },
    "/directory": {
      "get": {
        "operationId": "listDirectory",
        "summary": "List MPP/x402 directory endpoints",
        "tags": ["Network"],
        "security": [],
        "parameters": [
          { "name": "q", "in": "query", "schema": { "type": "string" } },
          {
            "name": "rail",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": ["mpp", "x402", "any"],
              "default": "any"
            }
          },
          {
            "name": "probe_status",
            "in": "query",
            "schema": { "type": "string" },
            "description": "Comma list of probe statuses"
          },
          {
            "name": "payment_ready",
            "in": "query",
            "schema": { "type": "string", "enum": ["1", "true", "yes"] }
          },
          {
            "name": "max_probe_age_hours",
            "in": "query",
            "schema": { "type": "integer", "minimum": 1, "maximum": 720 }
          },
          { "name": "network", "in": "query", "schema": { "type": "string" } },
          {
            "name": "source",
            "in": "query",
            "schema": { "type": "string" },
            "description": "Comma list of catalog sources (rill,partner for curated can-pay)"
          },
          {
            "name": "limit",
            "in": "query",
            "schema": { "type": "integer", "minimum": 1, "maximum": 100 }
          },
          { "name": "cursor", "in": "query", "schema": { "type": "string" } }
        ],
        "responses": {
          "200": {
            "description": "profiles[] ranked by directory_rank with pay_url, probe fields, optional body_hint, next_cursor",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": { "type": "boolean" },
                    "profiles": {
                      "type": "array",
                      "items": { "type": "object" }
                    },
                    "next_cursor": { "type": "string", "nullable": true }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/directory/sync": {
      "post": {
        "operationId": "syncDirectory",
        "summary": "Sync payment directory catalog (owner)",
        "description": "Reindex catalogs then probe every pay_url for a real 402/x402/MPP challenge; returns probe counts and appends probe history",
        "tags": ["Network"],
        "security": [{ "OwnerJwt": [] }],
        "parameters": [{ "$ref": "#/components/parameters/IdempotencyKey" }],
        "responses": {
          "200": {
            "description": "Sync status including probe totals by classification",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": { "type": "boolean" },
                    "probed": { "type": "integer" }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Error" }
        }
      }
    },
    "/directory/{id}": {
      "get": {
        "operationId": "getDirectoryProfile",
        "summary": "Get one directory profile",
        "tags": ["Network"],
        "security": [],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": { "type": "string" }
          }
        ],
        "responses": {
          "200": {
            "description": "profile",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": { "type": "boolean" },
                    "id": { "type": "string" },
                    "pay_url": { "type": "string" },
                    "body_hint": {
                      "type": "object",
                      "nullable": true,
                      "description": "JSON body the seller expects. Substitute your own values."
                    }
                  }
                }
              }
            }
          },
          "404": { "$ref": "#/components/responses/Error" }
        }
      }
    },
    "/accounts/{id}/fund-checkout": {
      "post": {
        "operationId": "createFundCheckout",
        "summary": "Stripe Checkout top-up",
        "tags": ["Spend"],
        "security": [{ "OwnerJwt": [] }],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": { "type": "string" }
          },
          { "$ref": "#/components/parameters/IdempotencyKeyRequired" }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "amount_cents": { "type": "integer" },
                  "hosted": { "type": "boolean" }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "funding_intent_id, amount, processing_fee, total_charged; client_secret (embedded) or checkout_url when hosted=true",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": { "type": "boolean" },
                    "funding_intent_id": { "type": "string" },
                    "amount": { "type": "integer" },
                    "checkout_url": { "type": "string" },
                    "client_secret": { "type": "string" },
                    "request_id": { "type": "string" }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/Error" },
          "401": { "$ref": "#/components/responses/Error" },
          "429": { "$ref": "#/components/responses/Error" }
        }
      }
    },
    "/accounts/{id}/spend-attempts": {
      "get": {
        "operationId": "listOwnerSpendAttempts",
        "summary": "List open-rail spend attempts (owner)",
        "tags": ["Spend"],
        "security": [{ "OwnerJwt": [] }],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": { "type": "string" }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": { "type": "integer", "default": 50 }
          }
        ],
        "responses": {
          "200": {
            "description": "attempts[] for MPP/x402 pay-url",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": { "type": "boolean" },
                    "attempts": {
                      "type": "array",
                      "items": { "type": "object" }
                    }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Error" }
        }
      }
    },
    "/wallets": {
      "post": {
        "operationId": "createVirtualWallet",
        "summary": "Mint virtual wallet (rill_vw_*)",
        "tags": ["Spend"],
        "security": [{ "OwnerJwt": [] }],
        "parameters": [{ "$ref": "#/components/parameters/IdempotencyKey" }],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "account_wallet_id": { "type": "string" },
                  "period_allowance_cents": { "type": "integer" },
                  "max_transaction_cents": { "type": "integer" }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "VW created (api_key shown once)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": { "type": "boolean" },
                    "id": { "type": "string" },
                    "api_key": { "type": "string" },
                    "request_id": { "type": "string" }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Error" }
        }
      }
    },
    "/spend/pay-url": {
      "post": {
        "operationId": "createSpendPayUrl",
        "summary": "Pay any MPP or x402 URL (primary Spend)",
        "description": "Probe URL for 402, fulfill open-rail challenge under VW policy, debit prepaid account wallet. Requires RILL_SPEND_EVM_PRIVATE_KEY on the server for crypto rails.",
        "tags": ["Spend"],
        "security": [{ "VirtualWallet": [] }],
        "parameters": [{ "$ref": "#/components/parameters/IdempotencyKey" }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["url"],
                "properties": {
                  "url": { "type": "string", "format": "uri" },
                  "directory_id": { "type": "string" },
                  "method": {
                    "type": "string",
                    "default": "GET",
                    "description": "HTTP method forwarded to the target. Defaults to GET unless the catalog probe_method is POST."
                  },
                  "headers": {
                    "type": "object",
                    "additionalProperties": { "type": "string" },
                    "description": "Extra request headers forwarded to the target"
                  },
                  "body": {
                    "description": "Request body forwarded on POST/PUT/PATCH. Objects are JSON-encoded. When the directory row has body_hint, copy that shape and substitute your own values.",
                    "oneOf": [{ "type": "string" }, { "type": "object" }]
                  },
                  "max_amount": { "type": "number" },
                  "max_amount_cents": { "type": "integer" },
                  "prefer_rail": {
                    "type": "string",
                    "enum": ["auto", "mpp", "x402"],
                    "default": "auto"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Paid, replayed, or already unlocked (no 402)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": { "type": "boolean" },
                    "paid": { "type": "boolean" },
                    "replayed": { "type": "boolean" },
                    "attempt_id": { "type": "string" },
                    "rail": {
                      "type": "string",
                      "enum": ["mpp", "x402", "rill"]
                    },
                    "amount": { "type": "string" },
                    "platform_fee": { "type": "string" },
                    "http_status": { "type": "integer" },
                    "headers": {
                      "type": "object",
                      "additionalProperties": { "type": "string" }
                    },
                    "body": {
                      "type": "string",
                      "description": "Upstream unlock body, truncated at 8192 chars"
                    },
                    "body_truncated": { "type": "boolean" },
                    "ledger_entry_id": { "type": "string", "nullable": true },
                    "receipt_id": {
                      "type": "string",
                      "nullable": true,
                      "description": "Rill receipt on ledger Accept gates; open-rail alias of the upstream payment-receipt / tx_hash"
                    },
                    "tx_hash": { "type": "string", "nullable": true },
                    "stripe_payment_intent_id": {
                      "type": "string",
                      "nullable": true
                    },
                    "request_id": { "type": "string" }
                  }
                }
              }
            }
          },
          "402": { "$ref": "#/components/responses/Error" },
          "422": { "$ref": "#/components/responses/Error" },
          "429": { "$ref": "#/components/responses/Error" },
          "502": { "$ref": "#/components/responses/Error" }
        }
      }
    },
    "/spend/attempts": {
      "get": {
        "operationId": "listSpendAttempts",
        "summary": "List open-rail spend attempts (VW key)",
        "tags": ["Spend"],
        "security": [{ "VirtualWallet": [] }],
        "responses": {
          "200": {
            "description": "attempts[]",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": { "type": "boolean" },
                    "attempts": {
                      "type": "array",
                      "items": { "type": "object" }
                    }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Error" }
        }
      }
    },
    "/pay": {
      "post": {
        "operationId": "createLedgerPay",
        "summary": "Background ledger: pay resource or transfer to handle/FQDN",
        "tags": ["Network"],
        "security": [{ "VirtualWallet": [] }],
        "parameters": [
          { "$ref": "#/components/parameters/IdempotencyKeyRequired" }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "resource_id": { "type": "string" },
                  "to": { "type": "string" },
                  "amount": { "type": "integer" },
                  "amount_cents": { "type": "integer" }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "receipt_id",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": { "type": "boolean" },
                    "receipt_id": { "type": "string" },
                    "request_id": { "type": "string" }
                  }
                }
              }
            }
          },
          "402": { "$ref": "#/components/responses/Error" },
          "409": { "$ref": "#/components/responses/Error" }
        }
      }
    },
    "/access/verify": {
      "post": {
        "operationId": "verifyReceipt",
        "summary": "Verify receipt (rcpt_* or open-rail payment intent id)",
        "tags": ["Accept"],
        "security": [],
        "parameters": [{ "$ref": "#/components/parameters/IdempotencyKey" }],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "receipt_id": { "type": "string" }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Receipt valid; rail is public mpp | x402 | rill",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": { "type": "boolean" },
                    "valid": { "type": "boolean" },
                    "rail": {
                      "type": "string",
                      "enum": ["mpp", "x402", "rill"]
                    }
                  }
                }
              }
            }
          },
          "404": { "$ref": "#/components/responses/Error" }
        }
      }
    },
    "/sellers": {
      "get": {
        "operationId": "listSellers",
        "summary": "List sellers for owner",
        "tags": ["Accept"],
        "security": [{ "OwnerJwt": [] }],
        "responses": {
          "200": {
            "description": "Sellers (no secrets)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": { "type": "boolean" },
                    "sellers": {
                      "type": "array",
                      "items": { "type": "object" }
                    }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Error" }
        }
      },
      "post": {
        "operationId": "createSeller",
        "summary": "Create Accept seller (rill_sk_*)",
        "tags": ["Accept"],
        "security": [{ "OwnerJwt": [] }],
        "parameters": [{ "$ref": "#/components/parameters/IdempotencyKey" }],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": { "type": "string" },
                  "website_url": {
                    "type": "string",
                    "description": "https company website for directory listing"
                  },
                  "description": {
                    "type": "string",
                    "description": "Short public listing copy"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Seller + api_key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": { "type": "boolean" },
                    "id": { "type": "string" },
                    "api_key": { "type": "string" }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Error" }
        }
      }
    },
    "/sellers/{id}/resources": {
      "get": {
        "operationId": "listSellerResources",
        "summary": "List seller resources (owner JWT)",
        "tags": ["Accept"],
        "security": [{ "OwnerJwt": [] }],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": { "type": "string" }
          }
        ],
        "responses": {
          "200": {
            "description": "Resources",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": { "type": "boolean" },
                    "resources": {
                      "type": "array",
                      "items": { "type": "object" }
                    }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Error" }
        }
      },
      "post": {
        "operationId": "createSellerResource",
        "summary": "Create priced resource (owner JWT)",
        "tags": ["Accept"],
        "security": [{ "OwnerJwt": [] }],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": { "type": "string" }
          },
          { "$ref": "#/components/parameters/IdempotencyKey" }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": { "type": "string" },
                  "price_cents": { "type": "integer" }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Resource created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": { "type": "boolean" },
                    "id": { "type": "string" },
                    "gate_url": { "type": "string" },
                    "pay_url": { "type": "string" }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Error" }
        }
      }
    },
    "/sellers/{id}/connect/sync": {
      "post": {
        "operationId": "syncSellerConnect",
        "summary": "Sync Express Connect status (owner JWT)",
        "tags": ["Accept"],
        "security": [{ "OwnerJwt": [] }],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": { "type": "string" }
          },
          { "$ref": "#/components/parameters/IdempotencyKey" }
        ],
        "responses": {
          "200": {
            "description": "Connect status",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": { "type": "boolean" },
                    "payouts_enabled": { "type": "boolean" }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Error" }
        }
      }
    },
    "/resources": {
      "post": {
        "operationId": "createResource",
        "summary": "Create priced resource (returns gate_url)",
        "description": "Accept SKU. Response resource includes gate_url (agents pay this) and pay_url (human pay page; MCP/CLI call it pay_page_url).",
        "tags": ["Accept"],
        "security": [{ "SellerKey": [] }],
        "parameters": [{ "$ref": "#/components/parameters/IdempotencyKey" }],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["path_or_tool", "amount"],
                "properties": {
                  "path_or_tool": { "type": "string" },
                  "amount": {
                    "type": "number",
                    "description": "USD price (decimal)"
                  },
                  "resource_type": {
                    "type": "string",
                    "enum": ["http", "mcp"],
                    "default": "http"
                  },
                  "sku_kind": {
                    "type": "string",
                    "enum": ["one_shot", "credit_topup"],
                    "default": "one_shot",
                    "description": "one_shot unlocks one call; credit_topup grants credits on the seller side"
                  },
                  "credits": {
                    "type": "integer",
                    "minimum": 1,
                    "description": "credit_topup only: credits granted per payment"
                  },
                  "credit_unit": {
                    "type": "string",
                    "description": "credit_topup only: unit label such as api_calls"
                  },
                  "metadata": {
                    "type": "object",
                    "description": "Free-form; echoed as metadata on payment.succeeded"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Resource created with gate_url and pay_url",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": { "type": "boolean" },
                    "id": { "type": "string" },
                    "gate_url": { "type": "string" },
                    "pay_url": { "type": "string" }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Error" }
        }
      }
    },
    "/sellers/me": {
      "patch": {
        "operationId": "updateSellerMe",
        "summary": "Update seller listing fields",
        "description": "Seller key. Optional website_url (https) and description copied into the directory on reindex; retain_spend_response_body opts out of Spend response-body logging for your hosts.",
        "tags": ["Accept"],
        "security": [{ "SellerKey": [] }],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "website_url": { "type": "string" },
                  "description": { "type": "string" },
                  "retain_spend_response_body": {
                    "type": "boolean",
                    "description": "false: Rill stores only status and headers (no response body) for Spend pays to this seller's hosts"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated seller (no secret)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": { "type": "boolean" },
                    "id": { "type": "string" },
                    "website_url": { "type": "string", "nullable": true },
                    "description": { "type": "string", "nullable": true }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Error" }
        }
      }
    },
    "/sellers/me/payments": {
      "patch": {
        "operationId": "enableSellerPayments",
        "summary": "Enable MPP/x402 on seller gates",
        "description": "Turn on open-rail payments for gate_url. Optional stripe_profile_id. Settlement lands in Stripe.",
        "tags": ["Accept"],
        "security": [{ "SellerKey": [] }],
        "parameters": [{ "$ref": "#/components/parameters/IdempotencyKey" }],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "mpp_enabled": { "type": "boolean" },
                  "x402_enabled": { "type": "boolean" },
                  "stripe_profile_id": { "type": "string" }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Seller with mpp_enabled / x402_enabled",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": { "type": "boolean" },
                    "mpp_enabled": { "type": "boolean" },
                    "x402_enabled": { "type": "boolean" }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Error" }
        }
      }
    },
    "/r/{resourceId}": {
      "get": {
        "operationId": "getHostedGate",
        "summary": "Hosted gate (MPP/x402 402 or unlock)",
        "tags": ["Accept"],
        "security": [],
        "parameters": [
          {
            "name": "resourceId",
            "in": "path",
            "required": true,
            "schema": { "type": "string" }
          },
          {
            "name": "X-Rill-Receipt",
            "in": "header",
            "required": false,
            "schema": { "type": "string" }
          },
          {
            "name": "Payment-Receipt",
            "in": "header",
            "required": false,
            "schema": { "type": "string" }
          },
          {
            "name": "PAYMENT-RESPONSE",
            "in": "header",
            "required": false,
            "schema": { "type": "string" }
          }
        ],
        "responses": {
          "200": { "description": "Unlocked" },
          "402": { "$ref": "#/components/responses/Error" }
        }
      }
    },
    "/demo/echo": {
      "get": {
        "operationId": "getDemoEcho",
        "summary": "Seed demo unlock",
        "tags": ["Agent"],
        "security": [],
        "parameters": [
          {
            "name": "X-Rill-Receipt",
            "in": "header",
            "required": true,
            "schema": { "type": "string" }
          }
        ],
        "responses": {
          "200": {
            "description": "Unlocked echo",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": { "type": "boolean" },
                    "echo": { "type": "string" }
                  }
                }
              }
            }
          },
          "402": { "$ref": "#/components/responses/Error" }
        }
      }
    },
    "/webhooks": {
      "post": {
        "operationId": "createWebhook",
        "summary": "Register webhook (payment.succeeded unlocks your product)",
        "description": "Defaults include payment.succeeded. Save the signing secret once to verify X-Rill-Signature.",
        "tags": ["Webhooks"],
        "security": [{ "OwnerJwt": [] }],
        "parameters": [{ "$ref": "#/components/parameters/IdempotencyKey" }],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "url": { "type": "string", "format": "uri" },
                  "events": { "type": "array", "items": { "type": "string" } }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Endpoint + signing secret",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": { "type": "boolean" },
                    "id": { "type": "string" },
                    "signing_secret": { "type": "string" }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Error" }
        }
      }
    }
  },
  "components": {
    "parameters": {
      "IdempotencyKey": {
        "name": "Idempotency-Key",
        "in": "header",
        "required": false,
        "schema": { "type": "string" },
        "description": "Replay-safe key for mutating writes. Conflict → 409; replay → Idempotency-Replayed."
      },
      "IdempotencyKeyRequired": {
        "name": "Idempotency-Key",
        "in": "header",
        "required": true,
        "schema": { "type": "string" },
        "description": "Required replay-safe key for this write."
      }
    },
    "headers": {
      "XApiVersion": {
        "schema": { "type": "string", "example": "1.1.0" },
        "description": "Current API version"
      },
      "XRateLimitLimit": {
        "schema": { "type": "integer" },
        "description": "Requests allowed in the current window"
      },
      "XRateLimitRemaining": {
        "schema": { "type": "integer" },
        "description": "Requests remaining in the current window"
      },
      "XRateLimitReset": {
        "schema": { "type": "integer" },
        "description": "Unix timestamp when the window resets"
      },
      "RetryAfter": {
        "schema": { "type": "integer" },
        "description": "Seconds to wait after 429"
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "required": ["ok", "error"],
        "properties": {
          "ok": { "type": "boolean", "enum": [false] },
          "error": {
            "type": "object",
            "required": ["code", "message"],
            "properties": {
              "code": { "type": "string" },
              "message": { "type": "string" },
              "details": { "type": "object", "additionalProperties": true }
            }
          },
          "request_id": { "type": "string" }
        }
      }
    },
    "responses": {
      "Error": {
        "description": "Typed error envelope",
        "headers": {
          "X-API-Version": { "$ref": "#/components/headers/XApiVersion" },
          "X-RateLimit-Limit": {
            "$ref": "#/components/headers/XRateLimitLimit"
          },
          "X-RateLimit-Remaining": {
            "$ref": "#/components/headers/XRateLimitRemaining"
          },
          "X-RateLimit-Reset": {
            "$ref": "#/components/headers/XRateLimitReset"
          },
          "Retry-After": { "$ref": "#/components/headers/RetryAfter" }
        },
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/Error" }
          }
        }
      }
    },
    "securitySchemes": {
      "OwnerJwt": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT"
      },
      "SellerKey": {
        "type": "apiKey",
        "in": "header",
        "name": "Authorization",
        "description": "Bearer rill_sk_*"
      },
      "VirtualWallet": {
        "type": "apiKey",
        "in": "header",
        "name": "Authorization",
        "description": "Bearer rill_vw_*"
      }
    }
  }
}
