{
  "openapi": "3.1.0",
  "info": {
    "title": "DeFi Garden API",
    "version": "0.1.0",
    "description": "Read-only, railed DeFi yield discovery and goal calculations"
  },
  "servers": [
    {
      "url": "https://www.defi.garden/api"
    }
  ],
  "paths": {
    "/": {
      "get": {
        "summary": "Describe the Yield API",
        "description": "Returns the API version, runtime endpoint inventory, data source, trust rails, and pricing boundary.",
        "operationId": "getApiContract",
        "responses": {
          "200": {
            "description": "The current API contract document",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ApiContract" }
              }
            }
          },
          "500": {
            "description": "Unexpected API handler failure",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ApiError" }
              }
            }
          },
          "503": {
            "description": "Live pool data is temporarily unavailable",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ApiError" }
              }
            }
          }
        }
      }
    },
    "/health": {
      "get": {
        "summary": "Check API health",
        "description": "Returns liveness, API version, response generation time, and the number of pools passing the current trust rails.",
        "operationId": "getApiHealth",
        "responses": {
          "200": {
            "description": "API health and railed pool availability",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/Health" }
              }
            }
          },
          "500": {
            "description": "Unexpected API handler failure",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ApiError" }
              }
            }
          },
          "503": {
            "description": "Live pool data is temporarily unavailable",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ApiError" }
              }
            }
          }
        }
      }
    },
    "/pools": {
      "get": {
        "summary": "Retrieve railed DeFi yield pools",
        "description": "Returns pools that pass the effective TVL floor and APY sanity limit, ordered by TVL descending.",
        "operationId": "getPools",
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": false,
            "description": "Case-insensitive substring match against the pool symbol.",
            "schema": { "type": "string" }
          },
          {
            "name": "chain",
            "in": "query",
            "required": false,
            "description": "Case-insensitive exact match against the chain name.",
            "schema": { "type": "string" }
          },
          {
            "name": "project",
            "in": "query",
            "required": false,
            "description": "Case-insensitive exact match against the project name.",
            "schema": { "type": "string" }
          },
          {
            "name": "minTvl",
            "in": "query",
            "required": false,
            "description": "Requested USD TVL floor. Values below the default rail are accepted but clamped up to it.",
            "schema": { "type": "number" }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum pools to return. Defaults to 50; values above 200 are accepted but clamped to 200.",
            "schema": {
              "type": "integer",
              "default": 50
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A filtered, railed page of pools",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/PoolList" }
              }
            }
          },
          "500": {
            "description": "Unexpected API handler failure",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ApiError" }
              }
            }
          },
          "503": {
            "description": "Live pool data is temporarily unavailable",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ApiError" }
              }
            }
          }
        }
      }
    },
    "/pools/{id}": {
      "get": {
        "summary": "Retrieve one pool",
        "description": "Returns one pool by DefiLlama pool id. Direct lookup preserves pools below the list rails and labels those conditions explicitly.",
        "operationId": "getPoolById",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "DefiLlama pool id.",
            "style": "simple",
            "explode": false,
            "schema": {
              "type": "string",
              "minLength": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The requested pool with direct-lookup rail labels",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/PoolDetail" }
              }
            }
          },
          "404": {
            "description": "No pool has the requested id",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ApiError" }
              }
            }
          },
          "500": {
            "description": "Unexpected API handler failure",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ApiError" }
              }
            }
          },
          "503": {
            "description": "Live pool data is temporarily unavailable",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ApiError" }
              }
            }
          }
        }
      }
    },
    "/pricing": {
      "get": {
        "summary": "Describe agentic-commerce pricing",
        "description": "Returns the route and MCP-tool price schedule plus the current x402 availability state. Reading this document is always free.",
        "operationId": "getPricing",
        "responses": {
          "200": {
            "description": "The current machine-readable pricing document",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/PricingDocument" }
              }
            }
          },
          "500": {
            "description": "Unexpected API handler failure",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ApiError" }
              }
            }
          },
          "503": {
            "description": "Live pool data is temporarily unavailable",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ApiError" }
              }
            }
          }
        }
      }
    },
    "/forever-number": {
      "get": {
        "summary": "Calculate capital for a recurring monthly bill",
        "description": "Calculates the lump-sum capital whose annual yield covers a recurring monthly amount, using either an explicit APY or a TVL-weighted blended rate from the railed pool set.",
        "operationId": "getForeverNumber",
        "parameters": [
          {
            "name": "monthly",
            "in": "query",
            "required": true,
            "description": "Positive recurring amount in USD per month.",
            "schema": {
              "type": "number",
              "exclusiveMinimum": 0
            }
          },
          {
            "name": "apy",
            "in": "query",
            "required": false,
            "description": "Annual percentage rate. When omitted, the API derives a TVL-weighted blended rate from railed pools.",
            "schema": { "type": "number" }
          }
        ],
        "responses": {
          "200": {
            "description": "Forever-number calculation, including an explicit non-financeable result when the rate cannot fund the bill",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ForeverNumber" }
              }
            }
          },
          "400": {
            "description": "Missing or invalid monthly or APY query parameter",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ApiError" }
              }
            }
          },
          "402": {
            "description": "Payment is required when x402 pricing is enabled",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/PaymentRequired" }
              }
            }
          },
          "500": {
            "description": "Unexpected API handler failure",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ApiError" }
              }
            }
          },
          "503": {
            "description": "Live pool data is temporarily unavailable",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ApiError" }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Rails": {
        "type": "object",
        "required": [
          "apySanityLimit",
          "minTvl",
          "apySanityLimitExplanation",
          "minTvlExplanation"
        ],
        "properties": {
          "apySanityLimit": { "type": "number" },
          "minTvl": { "type": "number" },
          "apySanityLimitExplanation": { "type": "string" },
          "minTvlExplanation": { "type": "string" }
        },
        "additionalProperties": false
      },
      "Endpoint": {
        "type": "object",
        "required": ["method", "path", "description"],
        "properties": {
          "method": {
            "type": "string",
            "enum": ["GET"]
          },
          "path": { "type": "string" },
          "description": { "type": "string" },
          "params": {
            "type": "object",
            "additionalProperties": { "type": "string" }
          }
        },
        "additionalProperties": false
      },
      "PricingAvailability": {
        "type": "object",
        "required": ["enabled", "mode"],
        "properties": {
          "enabled": { "type": "boolean" },
          "mode": {
            "type": "string",
            "enum": ["test", "live"]
          }
        },
        "additionalProperties": false
      },
      "ApiContractPricing": {
        "type": "object",
        "required": ["document", "boundary", "freeRoutes", "paidRoutes", "availability"],
        "properties": {
          "document": { "type": "string" },
          "boundary": { "type": "string" },
          "freeRoutes": {
            "type": "array",
            "items": { "type": "string" }
          },
          "paidRoutes": {
            "type": "array",
            "items": { "type": "string" }
          },
          "availability": { "$ref": "#/components/schemas/PricingAvailability" }
        },
        "additionalProperties": false
      },
      "ApiContract": {
        "type": "object",
        "required": ["name", "version", "description", "dataSource", "endpoints", "rails", "pricing"],
        "properties": {
          "name": { "type": "string" },
          "version": { "type": "string" },
          "description": { "type": "string" },
          "dataSource": {
            "type": "object",
            "required": ["upstream", "attribution", "cacheTtlSeconds"],
            "properties": {
              "upstream": {
                "type": "string",
                "format": "uri"
              },
              "attribution": { "type": "string" },
              "cacheTtlSeconds": {
                "type": "integer",
                "minimum": 0
              }
            },
            "additionalProperties": false
          },
          "endpoints": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/Endpoint" }
          },
          "rails": { "$ref": "#/components/schemas/Rails" },
          "pricing": { "$ref": "#/components/schemas/ApiContractPricing" }
        },
        "additionalProperties": false
      },
      "Health": {
        "type": "object",
        "required": ["ok", "version", "poolsAvailable", "generatedAt", "rails"],
        "properties": {
          "ok": {
            "type": "boolean",
            "const": true
          },
          "version": { "type": "string" },
          "poolsAvailable": {
            "type": "integer",
            "minimum": 0
          },
          "generatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "rails": { "$ref": "#/components/schemas/Rails" }
        },
        "additionalProperties": false
      },
      "Pool": {
        "type": "object",
        "required": [
          "pool",
          "chain",
          "project",
          "symbol",
          "tvlUsd",
          "apyBase",
          "apyReward",
          "totalApy",
          "apyMean30d",
          "poolMeta",
          "exposure",
          "ilRisk",
          "url"
        ],
        "properties": {
          "pool": { "type": "string" },
          "chain": { "type": "string" },
          "project": { "type": "string" },
          "symbol": { "type": "string" },
          "tvlUsd": { "type": "number" },
          "apyBase": { "type": ["number", "null"] },
          "apyReward": { "type": ["number", "null"] },
          "totalApy": { "type": "number" },
          "apyMean30d": { "type": ["number", "null"] },
          "poolMeta": { "type": ["string", "null"] },
          "exposure": { "type": ["string", "null"] },
          "ilRisk": { "type": ["string", "null"] },
          "url": { "type": ["string", "null"] }
        },
        "additionalProperties": false
      },
      "RailsApplied": {
        "type": "object",
        "required": ["minTvl", "minTvlClamped", "limit", "limitClamped"],
        "properties": {
          "minTvl": { "type": "number" },
          "minTvlClamped": { "type": "boolean" },
          "limit": {
            "type": "integer",
            "minimum": 1,
            "maximum": 200
          },
          "limitClamped": { "type": "boolean" }
        },
        "additionalProperties": false
      },
      "PoolList": {
        "type": "object",
        "required": ["pools", "count", "returned", "railsApplied", "rails"],
        "properties": {
          "pools": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/Pool" }
          },
          "count": {
            "type": "integer",
            "minimum": 0
          },
          "returned": {
            "type": "integer",
            "minimum": 0
          },
          "railsApplied": { "$ref": "#/components/schemas/RailsApplied" },
          "rails": { "$ref": "#/components/schemas/Rails" }
        },
        "additionalProperties": false
      },
      "PoolDetail": {
        "type": "object",
        "required": [
          "pool",
          "chain",
          "project",
          "symbol",
          "tvlUsd",
          "apyBase",
          "apyReward",
          "totalApy",
          "apyMean30d",
          "poolMeta",
          "exposure",
          "ilRisk",
          "url",
          "anomalous",
          "reason",
          "belowMinTvl",
          "belowMinTvlReason",
          "rails"
        ],
        "properties": {
          "pool": { "type": "string" },
          "chain": { "type": "string" },
          "project": { "type": "string" },
          "symbol": { "type": "string" },
          "tvlUsd": { "type": "number" },
          "apyBase": { "type": ["number", "null"] },
          "apyReward": { "type": ["number", "null"] },
          "totalApy": { "type": "number" },
          "apyMean30d": { "type": ["number", "null"] },
          "poolMeta": { "type": ["string", "null"] },
          "exposure": { "type": ["string", "null"] },
          "ilRisk": { "type": ["string", "null"] },
          "url": { "type": ["string", "null"] },
          "anomalous": { "type": "boolean" },
          "reason": { "type": ["string", "null"] },
          "belowMinTvl": { "type": "boolean" },
          "belowMinTvlReason": { "type": ["string", "null"] },
          "rails": { "$ref": "#/components/schemas/Rails" }
        },
        "additionalProperties": false
      },
      "ForeverNumber": {
        "type": "object",
        "required": [
          "monthly",
          "apyPct",
          "apySource",
          "financeable",
          "foreverNumber",
          "notFinanceableReason",
          "rails"
        ],
        "properties": {
          "monthly": {
            "type": "number",
            "exclusiveMinimum": 0
          },
          "apyPct": { "type": "number" },
          "apySource": {
            "type": "string",
            "enum": ["param", "blended"]
          },
          "financeable": { "type": "boolean" },
          "foreverNumber": { "type": ["number", "null"] },
          "notFinanceableReason": { "type": ["string", "null"] },
          "rails": { "$ref": "#/components/schemas/Rails" }
        },
        "additionalProperties": false
      },
      "PricingRoute": {
        "type": "object",
        "required": ["route", "method", "tier", "priceUsdcAtomic", "reason"],
        "properties": {
          "route": { "type": "string" },
          "method": {
            "type": "string",
            "enum": ["GET"]
          },
          "tier": {
            "type": "string",
            "enum": ["free", "paid"]
          },
          "priceUsdcAtomic": { "type": ["string", "null"] },
          "reason": { "type": "string" }
        },
        "additionalProperties": false
      },
      "PricingMcpTool": {
        "type": "object",
        "required": ["tool", "route", "tier", "priceUsdcAtomic"],
        "properties": {
          "tool": { "type": "string" },
          "route": { "type": "string" },
          "tier": {
            "type": ["string", "null"],
            "enum": ["free", "paid", null]
          },
          "priceUsdcAtomic": { "type": ["string", "null"] }
        },
        "additionalProperties": false
      },
      "PricingDocument": {
        "type": "object",
        "required": ["name", "protocol", "asset", "boundary", "routes", "mcpTools", "availability"],
        "properties": {
          "name": { "type": "string" },
          "protocol": {
            "type": "object",
            "required": ["name", "version"],
            "properties": {
              "name": {
                "type": "string",
                "const": "x402"
              },
              "version": {
                "type": "integer",
                "minimum": 1
              }
            },
            "additionalProperties": false
          },
          "asset": {
            "type": "object",
            "required": ["symbol", "decimals"],
            "properties": {
              "symbol": { "type": "string" },
              "decimals": {
                "type": "integer",
                "minimum": 0
              }
            },
            "additionalProperties": false
          },
          "boundary": { "type": "string" },
          "routes": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/PricingRoute" }
          },
          "mcpTools": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/PricingMcpTool" }
          },
          "availability": {
            "type": "object",
            "required": ["enabled", "mode", "statement"],
            "properties": {
              "enabled": { "type": "boolean" },
              "mode": {
                "type": "string",
                "enum": ["test", "live"]
              },
              "statement": { "type": "string" }
            },
            "additionalProperties": false
          }
        },
        "additionalProperties": false
      },
      "ApiError": {
        "type": "object",
        "required": ["error", "message", "rails"],
        "properties": {
          "error": {
            "type": "string",
            "enum": ["bad_request", "not_found", "internal_error", "upstream_unavailable"]
          },
          "message": { "type": "string" },
          "rails": { "$ref": "#/components/schemas/Rails" }
        },
        "additionalProperties": false
      },
      "PaymentRequired": {
        "type": "object",
        "required": ["x402Version", "error", "accepts"],
        "properties": {
          "x402Version": {
            "type": "integer",
            "minimum": 1
          },
          "error": { "type": "string" },
          "accepts": {
            "type": "array",
            "minItems": 1,
            "items": {
              "type": "object",
              "required": [
                "scheme",
                "network",
                "maxAmountRequired",
                "resource",
                "description",
                "mimeType",
                "payTo",
                "maxTimeoutSeconds",
                "asset",
                "extra"
              ],
              "properties": {
                "scheme": {
                  "type": "string",
                  "const": "exact"
                },
                "network": { "type": "string" },
                "maxAmountRequired": {
                  "type": "string",
                  "pattern": "^[0-9]+$"
                },
                "resource": {
                  "type": "string",
                  "format": "uri"
                },
                "description": { "type": "string" },
                "mimeType": {
                  "type": "string",
                  "const": "application/json"
                },
                "payTo": { "type": ["string", "null"] },
                "maxTimeoutSeconds": {
                  "type": "integer",
                  "minimum": 1
                },
                "asset": { "type": ["string", "null"] },
                "extra": {
                  "type": "object",
                  "required": ["name", "version", "docs", "freeAlternatives"],
                  "properties": {
                    "name": { "type": "string" },
                    "version": { "type": "string" },
                    "docs": { "type": "string" },
                    "freeAlternatives": {
                      "type": "array",
                      "items": { "type": "string" }
                    }
                  },
                  "additionalProperties": false
                }
              },
              "additionalProperties": false
            }
          }
        },
        "additionalProperties": false
      }
    }
  }
}
