{
  "openapi": "3.1.0",
  "info": {
    "title": "Toolshed — tools for agents",
    "version": "2026-08-19",
    "summary": "Hosted file conversions an agent can call over HTTP with nothing installed.",
    "description": "Post a file to a hosted tool and read the converted file back — nothing to install. Where we do not host the job, the entry names the tool worth reaching for and what bites about it. We prefer the plain deterministic tool wherever one works, and a model only where the answer is a judgment call.\n\nEvery hosted call is a paid call. There is no account and no key: a call with no payment answers HTTP 402 with an x402 envelope, and paying it is the whole authentication story. You are charged only for conversions that are actually served.\n\nThe same catalog is published as https://toolshed.lemon-agent.dev/catalog.json, https://toolshed.lemon-agent.dev/llms.txt and https://toolshed.lemon-agent.dev/llms-full.txt.",
    "license": {
      "name": "Proprietary",
      "identifier": "LicenseRef-Proprietary"
    }
  },
  "servers": [
    {
      "url": "https://toolshed.lemon-agent.dev",
      "description": "Production"
    }
  ],
  "tags": [
    {
      "name": "catalog",
      "description": "What this service can convert."
    },
    {
      "name": "convert",
      "description": "The hosted conversions. Priced per call in USDC via x402."
    }
  ],
  "paths": {
    "/check": {
      "get": {
        "operationId": "check",
        "summary": "List the conversions available for a pair.",
        "description": "Field-bound match: `from` is tested against the \"have\" side only, `to` against the \"need\" side only. Each parameter matches on a case-insensitive substring of the prose name OR on an exact alias, so extensions and MIME types work with or without a leading dot — `md`, `.md`, `text/markdown`. With no parameters the answer is every hosted tool. Touches no store, so it is exempt from every rate limit and costs nothing.",
        "tags": [
          "catalog"
        ],
        "parameters": [
          {
            "name": "from",
            "in": "query",
            "required": false,
            "description": "What you have. Max 64 characters.",
            "schema": {
              "type": "string",
              "maxLength": 64
            },
            "examples": {
              "prose": {
                "value": "markdown"
              },
              "extension": {
                "value": "md"
              },
              "dotted": {
                "value": ".md"
              },
              "mime": {
                "value": "text/markdown"
              }
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "description": "What you need. Max 64 characters.",
            "schema": {
              "type": "string",
              "maxLength": 64
            },
            "examples": {
              "prose": {
                "value": "html"
              },
              "mime": {
                "value": "text/html"
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The matching entries. An empty `matches` array is a valid answer, not an error.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "query",
                    "matches"
                  ],
                  "properties": {
                    "query": {
                      "type": "object",
                      "properties": {
                        "from": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "to": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      }
                    },
                    "matches": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "id",
                          "x",
                          "y",
                          "hosted",
                          "local",
                          "url"
                        ],
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "The id to POST to /convert/{id}."
                          },
                          "x": {
                            "type": "string",
                            "description": "What it takes, in prose."
                          },
                          "y": {
                            "type": "string",
                            "description": "What it produces, in prose."
                          },
                          "hosted": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "description": "Null for a local-only reference — there is no endpoint to call.",
                            "properties": {
                              "path": {
                                "type": "string"
                              },
                              "status": {
                                "type": "string",
                                "enum": [
                                  "live",
                                  "planned"
                                ]
                              },
                              "free_tier_daily": {
                                "type": "integer",
                                "description": "Free conversions per caller per UTC day, as the Worker enforces it right now. 0 means every call is a paid call."
                              },
                              "price": {
                                "oneOf": [
                                  {
                                    "type": "string",
                                    "enum": [
                                      "free"
                                    ]
                                  },
                                  {
                                    "type": "object",
                                    "properties": {
                                      "amount_usd": {
                                        "type": "number"
                                      },
                                      "scheme": {
                                        "type": "string"
                                      }
                                    }
                                  }
                                ]
                              }
                            }
                          },
                          "local": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "description": "The tool to run yourself instead.",
                            "properties": {
                              "tool": {
                                "type": "string"
                              },
                              "install": {
                                "type": "string"
                              }
                            }
                          },
                          "url": {
                            "type": "string",
                            "format": "uri"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "A parameter is longer than 64 characters.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "A plain sentence naming what went wrong."
                    }
                  }
                }
              }
            }
          },
          "405": {
            "description": "GET only.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "A plain sentence naming what went wrong."
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/convert/html-markdown": {
      "post": {
        "operationId": "convert_html_markdown",
        "summary": "Saved HTML page / static HTML file to Markdown",
        "description": "For HTML already on disk, pandoc's reader is exact and fast, and `--wrap=none` keeps the output diff-friendly. POST the raw file as the request body — no JSON wrapper, no multipart — and the converted file comes back as the response body. Input is capped at 256 KB. Every call is priced at $0.001/call · x402; a call with no X-PAYMENT header answers 402 with the envelope to pay against.",
        "tags": [
          "convert"
        ],
        "parameters": [
          {
            "name": "X-PAYMENT",
            "in": "header",
            "required": false,
            "description": "A base64-encoded x402 v1 payment payload, signed against the envelope in the 402 body.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "PAYMENT-SIGNATURE",
            "in": "header",
            "required": false,
            "description": "The x402 v2 equivalent: a base64-encoded v2 payment payload, signed against the envelope in the 402 PAYMENT-REQUIRED header. Send one header or the other, not both.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "description": "The raw Saved HTML page / static HTML file file, as the body. Up to 256 KB.",
          "content": {
            "text/plain": {
              "schema": {
                "type": "string"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The converted Markdown file.",
            "headers": {
              "x-payment-verified": {
                "description": "true when the payment was checked with the facilitator before serving.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "true",
                    "false"
                  ]
                }
              },
              "x-payment-error": {
                "description": "Present when the call was served WITHOUT its payment being verified.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "description": "The input could not be converted. Never charged: settlement is queued only for a conversion that was actually served.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "A plain sentence naming what went wrong."
                    }
                  }
                }
              }
            }
          },
          "402": {
            "description": "Payment required, in both x402 protocol versions at once. The body is the x402 v1 envelope; pay it with a v1 client and retry the same request with an X-PAYMENT header. The same 402 also carries the x402 v2 envelope, base64, in the PAYMENT-REQUIRED response header — that is where a v2 client looks, and it pays with a PAYMENT-SIGNATURE header. A body that also carries `invalidReason` means a payment WAS presented and the facilitator rejected it — retrying the same payload will fail identically.",
            "headers": {
              "PAYMENT-REQUIRED": {
                "description": "The x402 v2 PaymentRequired envelope, base64-encoded JSON: { x402Version: 2, resource, accepts, extensions.bazaar }. The same price, payTo and asset as the v1 body, in v2 spelling — `amount` instead of `maxAmountRequired`, the CAIP-2 network `eip155:8453` instead of `base`, and the outputSchema moved into extensions.bazaar.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "x402Version",
                    "accepts"
                  ],
                  "properties": {
                    "x402Version": {
                      "type": "integer",
                      "enum": [
                        1
                      ]
                    },
                    "error": {
                      "type": "string"
                    },
                    "invalidReason": {
                      "type": "string"
                    },
                    "invalidMessage": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "accepts": {
                      "type": "array",
                      "minItems": 1,
                      "items": {
                        "type": "object",
                        "description": "An x402 v1 payment requirements envelope — the terms to pay against.",
                        "required": [
                          "scheme",
                          "network",
                          "maxAmountRequired",
                          "resource",
                          "payTo",
                          "asset"
                        ],
                        "properties": {
                          "scheme": {
                            "type": "string",
                            "enum": [
                              "exact"
                            ]
                          },
                          "network": {
                            "type": "string",
                            "enum": [
                              "base"
                            ]
                          },
                          "maxAmountRequired": {
                            "type": "string",
                            "description": "Price in atomic units of `asset`. USDC has 6 decimals, so \"1000\" is $0.001.",
                            "examples": [
                              "1000"
                            ]
                          },
                          "resource": {
                            "type": "string",
                            "format": "uri",
                            "description": "The URL being paid for."
                          },
                          "description": {
                            "type": "string"
                          },
                          "mimeType": {
                            "type": "string",
                            "description": "Content type of the conversion this pays for."
                          },
                          "payTo": {
                            "type": "string",
                            "description": "The receiving address."
                          },
                          "maxTimeoutSeconds": {
                            "type": "integer",
                            "examples": [
                              60
                            ]
                          },
                          "asset": {
                            "type": "string",
                            "description": "USDC on Base.",
                            "examples": [
                              "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"
                            ]
                          },
                          "extra": {
                            "type": "object",
                            "description": "The EIP-712 domain the client signs over. USDC's on-chain name() is \"USD Coin\", which is not its ticker; a client that signs over the wrong domain produces a payment the facilitator cannot recover.",
                            "properties": {
                              "name": {
                                "type": "string"
                              },
                              "version": {
                                "type": "string"
                              }
                            }
                          },
                          "outputSchema": {
                            "type": "object",
                            "description": "How to call the resource and what comes back. `input.discoverable` marks it for indexing.",
                            "properties": {
                              "input": {
                                "type": "object",
                                "properties": {
                                  "type": {
                                    "type": "string",
                                    "enum": [
                                      "http"
                                    ]
                                  },
                                  "method": {
                                    "type": "string",
                                    "enum": [
                                      "POST"
                                    ]
                                  },
                                  "discoverable": {
                                    "type": "boolean"
                                  },
                                  "bodyType": {
                                    "type": "string"
                                  },
                                  "description": {
                                    "type": "string"
                                  }
                                }
                              },
                              "output": {
                                "type": "object",
                                "properties": {
                                  "type": {
                                    "type": "string"
                                  },
                                  "description": {
                                    "type": "string"
                                  }
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "413": {
            "description": "The body is larger than the 256 KB cap. Refused on the declared size, before any work.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "A plain sentence naming what went wrong."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Either this deployment has no receiving address configured (nothing to pay, so nothing to offer), or the per-caller daily ceiling on served calls is reached.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "A plain sentence naming what went wrong."
                    }
                  }
                }
              }
            }
          },
          "503": {
            "description": "The rate-limit store is unreachable. /convert fails closed rather than open.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "A plain sentence naming what went wrong."
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/convert/md-html": {
      "post": {
        "operationId": "convert_md_html",
        "summary": "Markdown to HTML",
        "description": "Markdown to HTML is a solved parse, so the only real questions are which dialect and which extensions. POST the raw file as the request body — no JSON wrapper, no multipart — and the converted file comes back as the response body. Input is capped at 256 KB. Every call is priced at $0.001/call · x402; a call with no X-PAYMENT header answers 402 with the envelope to pay against.",
        "tags": [
          "convert"
        ],
        "parameters": [
          {
            "name": "X-PAYMENT",
            "in": "header",
            "required": false,
            "description": "A base64-encoded x402 v1 payment payload, signed against the envelope in the 402 body.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "PAYMENT-SIGNATURE",
            "in": "header",
            "required": false,
            "description": "The x402 v2 equivalent: a base64-encoded v2 payment payload, signed against the envelope in the 402 PAYMENT-REQUIRED header. Send one header or the other, not both.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "description": "The raw Markdown file, as the body. Up to 256 KB.",
          "content": {
            "text/plain": {
              "schema": {
                "type": "string"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The converted HTML file.",
            "headers": {
              "x-payment-verified": {
                "description": "true when the payment was checked with the facilitator before serving.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "true",
                    "false"
                  ]
                }
              },
              "x-payment-error": {
                "description": "Present when the call was served WITHOUT its payment being verified.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "text/html": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "description": "The input could not be converted. Never charged: settlement is queued only for a conversion that was actually served.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "A plain sentence naming what went wrong."
                    }
                  }
                }
              }
            }
          },
          "402": {
            "description": "Payment required, in both x402 protocol versions at once. The body is the x402 v1 envelope; pay it with a v1 client and retry the same request with an X-PAYMENT header. The same 402 also carries the x402 v2 envelope, base64, in the PAYMENT-REQUIRED response header — that is where a v2 client looks, and it pays with a PAYMENT-SIGNATURE header. A body that also carries `invalidReason` means a payment WAS presented and the facilitator rejected it — retrying the same payload will fail identically.",
            "headers": {
              "PAYMENT-REQUIRED": {
                "description": "The x402 v2 PaymentRequired envelope, base64-encoded JSON: { x402Version: 2, resource, accepts, extensions.bazaar }. The same price, payTo and asset as the v1 body, in v2 spelling — `amount` instead of `maxAmountRequired`, the CAIP-2 network `eip155:8453` instead of `base`, and the outputSchema moved into extensions.bazaar.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "x402Version",
                    "accepts"
                  ],
                  "properties": {
                    "x402Version": {
                      "type": "integer",
                      "enum": [
                        1
                      ]
                    },
                    "error": {
                      "type": "string"
                    },
                    "invalidReason": {
                      "type": "string"
                    },
                    "invalidMessage": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "accepts": {
                      "type": "array",
                      "minItems": 1,
                      "items": {
                        "type": "object",
                        "description": "An x402 v1 payment requirements envelope — the terms to pay against.",
                        "required": [
                          "scheme",
                          "network",
                          "maxAmountRequired",
                          "resource",
                          "payTo",
                          "asset"
                        ],
                        "properties": {
                          "scheme": {
                            "type": "string",
                            "enum": [
                              "exact"
                            ]
                          },
                          "network": {
                            "type": "string",
                            "enum": [
                              "base"
                            ]
                          },
                          "maxAmountRequired": {
                            "type": "string",
                            "description": "Price in atomic units of `asset`. USDC has 6 decimals, so \"1000\" is $0.001.",
                            "examples": [
                              "1000"
                            ]
                          },
                          "resource": {
                            "type": "string",
                            "format": "uri",
                            "description": "The URL being paid for."
                          },
                          "description": {
                            "type": "string"
                          },
                          "mimeType": {
                            "type": "string",
                            "description": "Content type of the conversion this pays for."
                          },
                          "payTo": {
                            "type": "string",
                            "description": "The receiving address."
                          },
                          "maxTimeoutSeconds": {
                            "type": "integer",
                            "examples": [
                              60
                            ]
                          },
                          "asset": {
                            "type": "string",
                            "description": "USDC on Base.",
                            "examples": [
                              "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"
                            ]
                          },
                          "extra": {
                            "type": "object",
                            "description": "The EIP-712 domain the client signs over. USDC's on-chain name() is \"USD Coin\", which is not its ticker; a client that signs over the wrong domain produces a payment the facilitator cannot recover.",
                            "properties": {
                              "name": {
                                "type": "string"
                              },
                              "version": {
                                "type": "string"
                              }
                            }
                          },
                          "outputSchema": {
                            "type": "object",
                            "description": "How to call the resource and what comes back. `input.discoverable` marks it for indexing.",
                            "properties": {
                              "input": {
                                "type": "object",
                                "properties": {
                                  "type": {
                                    "type": "string",
                                    "enum": [
                                      "http"
                                    ]
                                  },
                                  "method": {
                                    "type": "string",
                                    "enum": [
                                      "POST"
                                    ]
                                  },
                                  "discoverable": {
                                    "type": "boolean"
                                  },
                                  "bodyType": {
                                    "type": "string"
                                  },
                                  "description": {
                                    "type": "string"
                                  }
                                }
                              },
                              "output": {
                                "type": "object",
                                "properties": {
                                  "type": {
                                    "type": "string"
                                  },
                                  "description": {
                                    "type": "string"
                                  }
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "413": {
            "description": "The body is larger than the 256 KB cap. Refused on the declared size, before any work.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "A plain sentence naming what went wrong."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Either this deployment has no receiving address configured (nothing to pay, so nothing to offer), or the per-caller daily ceiling on served calls is reached.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "A plain sentence naming what went wrong."
                    }
                  }
                }
              }
            }
          },
          "503": {
            "description": "The rate-limit store is unreachable. /convert fails closed rather than open.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "A plain sentence naming what went wrong."
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/convert/json-yaml": {
      "post": {
        "operationId": "convert_json_yaml",
        "summary": "JSON to YAML",
        "description": "mikefarah's yq speaks both formats natively (`yq -P`) and preserves comments through YAML edits, which is the whole reason to use it on real config files. POST the raw file as the request body — no JSON wrapper, no multipart — and the converted file comes back as the response body. Input is capped at 256 KB. Every call is priced at $0.001/call · x402; a call with no X-PAYMENT header answers 402 with the envelope to pay against.",
        "tags": [
          "convert"
        ],
        "parameters": [
          {
            "name": "X-PAYMENT",
            "in": "header",
            "required": false,
            "description": "A base64-encoded x402 v1 payment payload, signed against the envelope in the 402 body.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "PAYMENT-SIGNATURE",
            "in": "header",
            "required": false,
            "description": "The x402 v2 equivalent: a base64-encoded v2 payment payload, signed against the envelope in the 402 PAYMENT-REQUIRED header. Send one header or the other, not both.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "description": "The raw JSON file, as the body. Up to 256 KB.",
          "content": {
            "text/plain": {
              "schema": {
                "type": "string"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The converted YAML file.",
            "headers": {
              "x-payment-verified": {
                "description": "true when the payment was checked with the facilitator before serving.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "true",
                    "false"
                  ]
                }
              },
              "x-payment-error": {
                "description": "Present when the call was served WITHOUT its payment being verified.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/yaml": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "description": "The input could not be converted. Never charged: settlement is queued only for a conversion that was actually served.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "A plain sentence naming what went wrong."
                    }
                  }
                }
              }
            }
          },
          "402": {
            "description": "Payment required, in both x402 protocol versions at once. The body is the x402 v1 envelope; pay it with a v1 client and retry the same request with an X-PAYMENT header. The same 402 also carries the x402 v2 envelope, base64, in the PAYMENT-REQUIRED response header — that is where a v2 client looks, and it pays with a PAYMENT-SIGNATURE header. A body that also carries `invalidReason` means a payment WAS presented and the facilitator rejected it — retrying the same payload will fail identically.",
            "headers": {
              "PAYMENT-REQUIRED": {
                "description": "The x402 v2 PaymentRequired envelope, base64-encoded JSON: { x402Version: 2, resource, accepts, extensions.bazaar }. The same price, payTo and asset as the v1 body, in v2 spelling — `amount` instead of `maxAmountRequired`, the CAIP-2 network `eip155:8453` instead of `base`, and the outputSchema moved into extensions.bazaar.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "x402Version",
                    "accepts"
                  ],
                  "properties": {
                    "x402Version": {
                      "type": "integer",
                      "enum": [
                        1
                      ]
                    },
                    "error": {
                      "type": "string"
                    },
                    "invalidReason": {
                      "type": "string"
                    },
                    "invalidMessage": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "accepts": {
                      "type": "array",
                      "minItems": 1,
                      "items": {
                        "type": "object",
                        "description": "An x402 v1 payment requirements envelope — the terms to pay against.",
                        "required": [
                          "scheme",
                          "network",
                          "maxAmountRequired",
                          "resource",
                          "payTo",
                          "asset"
                        ],
                        "properties": {
                          "scheme": {
                            "type": "string",
                            "enum": [
                              "exact"
                            ]
                          },
                          "network": {
                            "type": "string",
                            "enum": [
                              "base"
                            ]
                          },
                          "maxAmountRequired": {
                            "type": "string",
                            "description": "Price in atomic units of `asset`. USDC has 6 decimals, so \"1000\" is $0.001.",
                            "examples": [
                              "1000"
                            ]
                          },
                          "resource": {
                            "type": "string",
                            "format": "uri",
                            "description": "The URL being paid for."
                          },
                          "description": {
                            "type": "string"
                          },
                          "mimeType": {
                            "type": "string",
                            "description": "Content type of the conversion this pays for."
                          },
                          "payTo": {
                            "type": "string",
                            "description": "The receiving address."
                          },
                          "maxTimeoutSeconds": {
                            "type": "integer",
                            "examples": [
                              60
                            ]
                          },
                          "asset": {
                            "type": "string",
                            "description": "USDC on Base.",
                            "examples": [
                              "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"
                            ]
                          },
                          "extra": {
                            "type": "object",
                            "description": "The EIP-712 domain the client signs over. USDC's on-chain name() is \"USD Coin\", which is not its ticker; a client that signs over the wrong domain produces a payment the facilitator cannot recover.",
                            "properties": {
                              "name": {
                                "type": "string"
                              },
                              "version": {
                                "type": "string"
                              }
                            }
                          },
                          "outputSchema": {
                            "type": "object",
                            "description": "How to call the resource and what comes back. `input.discoverable` marks it for indexing.",
                            "properties": {
                              "input": {
                                "type": "object",
                                "properties": {
                                  "type": {
                                    "type": "string",
                                    "enum": [
                                      "http"
                                    ]
                                  },
                                  "method": {
                                    "type": "string",
                                    "enum": [
                                      "POST"
                                    ]
                                  },
                                  "discoverable": {
                                    "type": "boolean"
                                  },
                                  "bodyType": {
                                    "type": "string"
                                  },
                                  "description": {
                                    "type": "string"
                                  }
                                }
                              },
                              "output": {
                                "type": "object",
                                "properties": {
                                  "type": {
                                    "type": "string"
                                  },
                                  "description": {
                                    "type": "string"
                                  }
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "413": {
            "description": "The body is larger than the 256 KB cap. Refused on the declared size, before any work.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "A plain sentence naming what went wrong."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Either this deployment has no receiving address configured (nothing to pay, so nothing to offer), or the per-caller daily ceiling on served calls is reached.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "A plain sentence naming what went wrong."
                    }
                  }
                }
              }
            }
          },
          "503": {
            "description": "The rate-limit store is unreachable. /convert fails closed rather than open.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "A plain sentence naming what went wrong."
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/convert/yaml-json": {
      "post": {
        "operationId": "convert_yaml_json",
        "summary": "YAML to JSON",
        "description": "`yq -o=json` is the local answer, and the direction that bites is this one: YAML is the larger language, so anchors, multi-document streams and unquoted `no`/`yes` all have to land somewhere in JSON. POST the raw file as the request body — no JSON wrapper, no multipart — and the converted file comes back as the response body. Input is capped at 256 KB. Every call is priced at $0.001/call · x402; a call with no X-PAYMENT header answers 402 with the envelope to pay against.",
        "tags": [
          "convert"
        ],
        "parameters": [
          {
            "name": "X-PAYMENT",
            "in": "header",
            "required": false,
            "description": "A base64-encoded x402 v1 payment payload, signed against the envelope in the 402 body.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "PAYMENT-SIGNATURE",
            "in": "header",
            "required": false,
            "description": "The x402 v2 equivalent: a base64-encoded v2 payment payload, signed against the envelope in the 402 PAYMENT-REQUIRED header. Send one header or the other, not both.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "description": "The raw YAML file, as the body. Up to 256 KB.",
          "content": {
            "text/plain": {
              "schema": {
                "type": "string"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The converted JSON file.",
            "headers": {
              "x-payment-verified": {
                "description": "true when the payment was checked with the facilitator before serving.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "true",
                    "false"
                  ]
                }
              },
              "x-payment-error": {
                "description": "Present when the call was served WITHOUT its payment being verified.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "description": "The input could not be converted. Never charged: settlement is queued only for a conversion that was actually served.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "A plain sentence naming what went wrong."
                    }
                  }
                }
              }
            }
          },
          "402": {
            "description": "Payment required, in both x402 protocol versions at once. The body is the x402 v1 envelope; pay it with a v1 client and retry the same request with an X-PAYMENT header. The same 402 also carries the x402 v2 envelope, base64, in the PAYMENT-REQUIRED response header — that is where a v2 client looks, and it pays with a PAYMENT-SIGNATURE header. A body that also carries `invalidReason` means a payment WAS presented and the facilitator rejected it — retrying the same payload will fail identically.",
            "headers": {
              "PAYMENT-REQUIRED": {
                "description": "The x402 v2 PaymentRequired envelope, base64-encoded JSON: { x402Version: 2, resource, accepts, extensions.bazaar }. The same price, payTo and asset as the v1 body, in v2 spelling — `amount` instead of `maxAmountRequired`, the CAIP-2 network `eip155:8453` instead of `base`, and the outputSchema moved into extensions.bazaar.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "x402Version",
                    "accepts"
                  ],
                  "properties": {
                    "x402Version": {
                      "type": "integer",
                      "enum": [
                        1
                      ]
                    },
                    "error": {
                      "type": "string"
                    },
                    "invalidReason": {
                      "type": "string"
                    },
                    "invalidMessage": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "accepts": {
                      "type": "array",
                      "minItems": 1,
                      "items": {
                        "type": "object",
                        "description": "An x402 v1 payment requirements envelope — the terms to pay against.",
                        "required": [
                          "scheme",
                          "network",
                          "maxAmountRequired",
                          "resource",
                          "payTo",
                          "asset"
                        ],
                        "properties": {
                          "scheme": {
                            "type": "string",
                            "enum": [
                              "exact"
                            ]
                          },
                          "network": {
                            "type": "string",
                            "enum": [
                              "base"
                            ]
                          },
                          "maxAmountRequired": {
                            "type": "string",
                            "description": "Price in atomic units of `asset`. USDC has 6 decimals, so \"1000\" is $0.001.",
                            "examples": [
                              "1000"
                            ]
                          },
                          "resource": {
                            "type": "string",
                            "format": "uri",
                            "description": "The URL being paid for."
                          },
                          "description": {
                            "type": "string"
                          },
                          "mimeType": {
                            "type": "string",
                            "description": "Content type of the conversion this pays for."
                          },
                          "payTo": {
                            "type": "string",
                            "description": "The receiving address."
                          },
                          "maxTimeoutSeconds": {
                            "type": "integer",
                            "examples": [
                              60
                            ]
                          },
                          "asset": {
                            "type": "string",
                            "description": "USDC on Base.",
                            "examples": [
                              "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"
                            ]
                          },
                          "extra": {
                            "type": "object",
                            "description": "The EIP-712 domain the client signs over. USDC's on-chain name() is \"USD Coin\", which is not its ticker; a client that signs over the wrong domain produces a payment the facilitator cannot recover.",
                            "properties": {
                              "name": {
                                "type": "string"
                              },
                              "version": {
                                "type": "string"
                              }
                            }
                          },
                          "outputSchema": {
                            "type": "object",
                            "description": "How to call the resource and what comes back. `input.discoverable` marks it for indexing.",
                            "properties": {
                              "input": {
                                "type": "object",
                                "properties": {
                                  "type": {
                                    "type": "string",
                                    "enum": [
                                      "http"
                                    ]
                                  },
                                  "method": {
                                    "type": "string",
                                    "enum": [
                                      "POST"
                                    ]
                                  },
                                  "discoverable": {
                                    "type": "boolean"
                                  },
                                  "bodyType": {
                                    "type": "string"
                                  },
                                  "description": {
                                    "type": "string"
                                  }
                                }
                              },
                              "output": {
                                "type": "object",
                                "properties": {
                                  "type": {
                                    "type": "string"
                                  },
                                  "description": {
                                    "type": "string"
                                  }
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "413": {
            "description": "The body is larger than the 256 KB cap. Refused on the declared size, before any work.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "A plain sentence naming what went wrong."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Either this deployment has no receiving address configured (nothing to pay, so nothing to offer), or the per-caller daily ceiling on served calls is reached.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "A plain sentence naming what went wrong."
                    }
                  }
                }
              }
            }
          },
          "503": {
            "description": "The rate-limit store is unreachable. /convert fails closed rather than open.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "A plain sentence naming what went wrong."
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/convert/csv-json": {
      "post": {
        "operationId": "convert_csv_json",
        "summary": "CSV to JSON",
        "description": "`csvjson data.csv` turns a header row plus records into an array of objects, which is the shape almost everything downstream wants. POST the raw file as the request body — no JSON wrapper, no multipart — and the converted file comes back as the response body. Input is capped at 256 KB. Every call is priced at $0.001/call · x402; a call with no X-PAYMENT header answers 402 with the envelope to pay against.",
        "tags": [
          "convert"
        ],
        "parameters": [
          {
            "name": "X-PAYMENT",
            "in": "header",
            "required": false,
            "description": "A base64-encoded x402 v1 payment payload, signed against the envelope in the 402 body.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "PAYMENT-SIGNATURE",
            "in": "header",
            "required": false,
            "description": "The x402 v2 equivalent: a base64-encoded v2 payment payload, signed against the envelope in the 402 PAYMENT-REQUIRED header. Send one header or the other, not both.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "description": "The raw CSV file, as the body. Up to 256 KB.",
          "content": {
            "text/plain": {
              "schema": {
                "type": "string"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The converted JSON file.",
            "headers": {
              "x-payment-verified": {
                "description": "true when the payment was checked with the facilitator before serving.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "true",
                    "false"
                  ]
                }
              },
              "x-payment-error": {
                "description": "Present when the call was served WITHOUT its payment being verified.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "description": "The input could not be converted. Never charged: settlement is queued only for a conversion that was actually served.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "A plain sentence naming what went wrong."
                    }
                  }
                }
              }
            }
          },
          "402": {
            "description": "Payment required, in both x402 protocol versions at once. The body is the x402 v1 envelope; pay it with a v1 client and retry the same request with an X-PAYMENT header. The same 402 also carries the x402 v2 envelope, base64, in the PAYMENT-REQUIRED response header — that is where a v2 client looks, and it pays with a PAYMENT-SIGNATURE header. A body that also carries `invalidReason` means a payment WAS presented and the facilitator rejected it — retrying the same payload will fail identically.",
            "headers": {
              "PAYMENT-REQUIRED": {
                "description": "The x402 v2 PaymentRequired envelope, base64-encoded JSON: { x402Version: 2, resource, accepts, extensions.bazaar }. The same price, payTo and asset as the v1 body, in v2 spelling — `amount` instead of `maxAmountRequired`, the CAIP-2 network `eip155:8453` instead of `base`, and the outputSchema moved into extensions.bazaar.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "x402Version",
                    "accepts"
                  ],
                  "properties": {
                    "x402Version": {
                      "type": "integer",
                      "enum": [
                        1
                      ]
                    },
                    "error": {
                      "type": "string"
                    },
                    "invalidReason": {
                      "type": "string"
                    },
                    "invalidMessage": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "accepts": {
                      "type": "array",
                      "minItems": 1,
                      "items": {
                        "type": "object",
                        "description": "An x402 v1 payment requirements envelope — the terms to pay against.",
                        "required": [
                          "scheme",
                          "network",
                          "maxAmountRequired",
                          "resource",
                          "payTo",
                          "asset"
                        ],
                        "properties": {
                          "scheme": {
                            "type": "string",
                            "enum": [
                              "exact"
                            ]
                          },
                          "network": {
                            "type": "string",
                            "enum": [
                              "base"
                            ]
                          },
                          "maxAmountRequired": {
                            "type": "string",
                            "description": "Price in atomic units of `asset`. USDC has 6 decimals, so \"1000\" is $0.001.",
                            "examples": [
                              "1000"
                            ]
                          },
                          "resource": {
                            "type": "string",
                            "format": "uri",
                            "description": "The URL being paid for."
                          },
                          "description": {
                            "type": "string"
                          },
                          "mimeType": {
                            "type": "string",
                            "description": "Content type of the conversion this pays for."
                          },
                          "payTo": {
                            "type": "string",
                            "description": "The receiving address."
                          },
                          "maxTimeoutSeconds": {
                            "type": "integer",
                            "examples": [
                              60
                            ]
                          },
                          "asset": {
                            "type": "string",
                            "description": "USDC on Base.",
                            "examples": [
                              "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"
                            ]
                          },
                          "extra": {
                            "type": "object",
                            "description": "The EIP-712 domain the client signs over. USDC's on-chain name() is \"USD Coin\", which is not its ticker; a client that signs over the wrong domain produces a payment the facilitator cannot recover.",
                            "properties": {
                              "name": {
                                "type": "string"
                              },
                              "version": {
                                "type": "string"
                              }
                            }
                          },
                          "outputSchema": {
                            "type": "object",
                            "description": "How to call the resource and what comes back. `input.discoverable` marks it for indexing.",
                            "properties": {
                              "input": {
                                "type": "object",
                                "properties": {
                                  "type": {
                                    "type": "string",
                                    "enum": [
                                      "http"
                                    ]
                                  },
                                  "method": {
                                    "type": "string",
                                    "enum": [
                                      "POST"
                                    ]
                                  },
                                  "discoverable": {
                                    "type": "boolean"
                                  },
                                  "bodyType": {
                                    "type": "string"
                                  },
                                  "description": {
                                    "type": "string"
                                  }
                                }
                              },
                              "output": {
                                "type": "object",
                                "properties": {
                                  "type": {
                                    "type": "string"
                                  },
                                  "description": {
                                    "type": "string"
                                  }
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "413": {
            "description": "The body is larger than the 256 KB cap. Refused on the declared size, before any work.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "A plain sentence naming what went wrong."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Either this deployment has no receiving address configured (nothing to pay, so nothing to offer), or the per-caller daily ceiling on served calls is reached.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "A plain sentence naming what went wrong."
                    }
                  }
                }
              }
            }
          },
          "503": {
            "description": "The rate-limit store is unreachable. /convert fails closed rather than open.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "A plain sentence naming what went wrong."
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}
