{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/asteroidxrpl-com/json-schema/asteroidxrpl-com-quote-response-schema.json",
  "title": "Indicative ASTEROID AMM quote",
  "x-generated": "2026-11-01",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/asteroidxrpl-com-openapi.json#/components/schemas/quote-response",
  "type": "object",
  "required": [
    "tokenId",
    "direction",
    "assetIn",
    "assetOut",
    "request",
    "lifecycle",
    "calculation",
    "quote",
    "pool",
    "warnings",
    "error",
    "executable",
    "claimStatus",
    "methodology",
    "limitations"
  ],
  "additionalProperties": false,
  "properties": {
    "tokenId": {
      "type": "string"
    },
    "direction": {
      "type": "string",
      "enum": [
        "xrp-to-asteroid",
        "asteroid-to-xrp"
      ]
    },
    "assetIn": {
      "type": "string"
    },
    "assetOut": {
      "type": "string"
    },
    "request": {
      "type": "object",
      "required": [
        "side",
        "amount",
        "slippageTolerancePct"
      ],
      "additionalProperties": false,
      "properties": {
        "side": {
          "type": "string",
          "enum": [
            "exact-in",
            "exact-out"
          ]
        },
        "amount": {
          "type": "string"
        },
        "slippageTolerancePct": {
          "type": [
            "string",
            "null"
          ]
        }
      }
    },
    "lifecycle": {
      "type": "object",
      "required": [
        "quoteId",
        "methodologyId",
        "methodologyVersion",
        "ledgerIndex",
        "observedAt",
        "maxAgeMs",
        "expiresAt",
        "remainingMs",
        "cache",
        "testVectors"
      ],
      "additionalProperties": false,
      "properties": {
        "quoteId": {
          "type": "string",
          "description": "Identifier for this estimate. It is a correlation handle only: it reserves nothing, cannot be redeemed and cannot be executed."
        },
        "methodologyId": {
          "type": "string"
        },
        "methodologyVersion": {
          "type": "string"
        },
        "ledgerIndex": {
          "type": [
            "integer",
            "null"
          ]
        },
        "observedAt": {
          "type": "string",
          "format": "date-time"
        },
        "maxAgeMs": {
          "type": "integer",
          "minimum": 0
        },
        "expiresAt": {
          "type": "string",
          "format": "date-time",
          "description": "observedAt + maxAgeMs, always measured from the original ledger observation and never restarted by a cache hit. After this instant the estimate must be discarded and the pool re-read. Expiry does not mean the estimate was ever executable."
        },
        "remainingMs": {
          "type": "integer",
          "minimum": 0,
          "description": "Freshness left on the original observation when the estimate was produced: maxAgeMs minus the age of the pool reading. A cache hit never restarts the window, so expiresAt always equals observedAt + maxAgeMs."
        },
        "cache": {
          "oneOf": [
            {
              "$schema": "https://json-schema.org/draft/2020-12/schema",
              "$id": "https://asteroidxrpl.com/schemas/v1/cache-freshness-metadata.json",
              "title": "Cache freshness metadata",
              "description": "Age disclosure for a reading served from the bounded single-flight server cache. A cached reading still states the validated ledger index and observation time it was produced from; its age is never hidden.",
              "type": "object",
              "required": [
                "hit",
                "cachedAt",
                "ageMs",
                "ttlMs"
              ],
              "additionalProperties": false,
              "properties": {
                "hit": {
                  "type": "boolean",
                  "description": "True when this response reused a cached reading."
                },
                "cachedAt": {
                  "type": "string",
                  "format": "date-time"
                },
                "ageMs": {
                  "type": "integer",
                  "minimum": 0
                },
                "ttlMs": {
                  "type": "integer",
                  "minimum": 0
                },
                "key": {
                  "type": "string"
                }
              }
            },
            {
              "type": "null"
            }
          ]
        },
        "testVectors": {
          "type": "string",
          "format": "uri"
        }
      }
    },
    "calculation": {
      "oneOf": [
        {
          "$ref": "#/$defs/calculation-input"
        },
        {
          "type": "null"
        }
      ]
    },
    "quote": {
      "oneOf": [
        {
          "$ref": "#/$defs/calculation-result"
        },
        {
          "type": "null"
        }
      ]
    },
    "pool": {
      "type": "object",
      "required": [
        "account",
        "xrpReserve",
        "asteroidReserve",
        "tradingFeeUnits",
        "tradingFeePct"
      ],
      "additionalProperties": false,
      "properties": {
        "account": {
          "type": [
            "string",
            "null"
          ]
        },
        "xrpReserve": {
          "type": [
            "string",
            "null"
          ],
          "pattern": "^-?[0-9]+(\\.[0-9]+)?$",
          "description": "Exact decimal string. Never rounded for transport. Null means unreadable, not zero."
        },
        "asteroidReserve": {
          "type": [
            "string",
            "null"
          ],
          "pattern": "^-?[0-9]+(\\.[0-9]+)?$",
          "description": "Exact decimal string. Never rounded for transport. Null means unreadable, not zero."
        },
        "tradingFeeUnits": {
          "type": [
            "integer",
            "null"
          ]
        },
        "tradingFeePct": {
          "type": [
            "string",
            "null"
          ],
          "pattern": "^-?[0-9]+(\\.[0-9]+)?$",
          "description": "Exact decimal string. Never rounded for transport. Null means unreadable, not zero."
        }
      }
    },
    "warnings": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "code",
          "severity",
          "message"
        ],
        "additionalProperties": false,
        "properties": {
          "code": {
            "type": "string"
          },
          "severity": {
            "type": "string",
            "enum": [
              "info",
              "warning"
            ]
          },
          "message": {
            "type": "string"
          }
        }
      }
    },
    "error": {
      "oneOf": [
        {
          "type": "object",
          "required": [
            "code",
            "message"
          ],
          "additionalProperties": false,
          "properties": {
            "code": {
              "type": "string"
            },
            "message": {
              "type": "string"
            }
          }
        },
        {
          "type": "null"
        }
      ]
    },
    "executable": {
      "const": false,
      "description": "Always false. This service never produces an executable quote."
    },
    "claimStatus": {
      "type": "string",
      "enum": [
        "ledger-verified",
        "owner-confirmed",
        "independently-sourced",
        "derived",
        "aspirational",
        "unresolved"
      ]
    },
    "methodology": {
      "type": "string"
    },
    "limitations": {
      "type": "array",
      "items": {
        "type": "string"
      }
    }
  },
  "$defs": {
    "calculation-input": {
      "title": "Calculation input",
      "description": "The exact inputs a derived value was computed from, republished so the calculation can be reproduced independently against the published test vectors.",
      "type": "object",
      "required": [
        "formulaId",
        "methodologyId",
        "methodologyVersion",
        "direction",
        "side",
        "amount",
        "poolIn",
        "poolOut",
        "assetIn",
        "assetOut",
        "tradingFeeUnits",
        "feeFraction",
        "slippageTolerancePct",
        "rounding"
      ],
      "additionalProperties": false,
      "properties": {
        "formulaId": {
          "type": "string",
          "const": "constant-product-swap"
        },
        "methodologyId": {
          "type": "string"
        },
        "methodologyVersion": {
          "type": "string"
        },
        "direction": {
          "type": "string",
          "enum": [
            "xrp-to-asteroid",
            "asteroid-to-xrp"
          ]
        },
        "side": {
          "type": "string",
          "enum": [
            "exact-in",
            "exact-out"
          ]
        },
        "amount": {
          "type": "string"
        },
        "poolIn": {
          "type": [
            "string",
            "null"
          ],
          "pattern": "^-?[0-9]+(\\.[0-9]+)?$",
          "description": "Exact decimal string. Never rounded for transport. Null means unreadable, not zero."
        },
        "poolOut": {
          "type": [
            "string",
            "null"
          ],
          "pattern": "^-?[0-9]+(\\.[0-9]+)?$",
          "description": "Exact decimal string. Never rounded for transport. Null means unreadable, not zero."
        },
        "assetIn": {
          "type": "string"
        },
        "assetOut": {
          "type": "string"
        },
        "tradingFeeUnits": {
          "type": "integer",
          "minimum": 0
        },
        "feeFraction": {
          "type": "string"
        },
        "slippageTolerancePct": {
          "type": [
            "string",
            "null"
          ]
        },
        "rounding": {
          "type": "string"
        }
      }
    },
    "calculation-result": {
      "title": "Calculation result",
      "description": "The result of a constant-product AMM calculation. Every quantity is an exact decimal string. Indicative and never executable.",
      "type": "object",
      "required": [
        "side",
        "amountIn",
        "amountOut",
        "feeAmountIn",
        "tradingFeeUnits",
        "tradingFeePct",
        "spotPrice",
        "effectivePrice",
        "priceImpactPct",
        "poolUtilisationPct",
        "poolInAfter",
        "poolOutAfter",
        "slippageTolerancePct",
        "minimumReceived",
        "maximumPaid"
      ],
      "additionalProperties": false,
      "properties": {
        "side": {
          "type": "string",
          "enum": [
            "exact-in",
            "exact-out"
          ]
        },
        "amountIn": {
          "type": [
            "string",
            "null"
          ],
          "pattern": "^-?[0-9]+(\\.[0-9]+)?$",
          "description": "Exact decimal string. Never rounded for transport. Null means unreadable, not zero."
        },
        "amountOut": {
          "type": [
            "string",
            "null"
          ],
          "pattern": "^-?[0-9]+(\\.[0-9]+)?$",
          "description": "Exact decimal string. Never rounded for transport. Null means unreadable, not zero."
        },
        "feeAmountIn": {
          "type": [
            "string",
            "null"
          ],
          "pattern": "^-?[0-9]+(\\.[0-9]+)?$",
          "description": "Exact decimal string. Never rounded for transport. Null means unreadable, not zero."
        },
        "tradingFeeUnits": {
          "type": "integer"
        },
        "tradingFeePct": {
          "type": [
            "string",
            "null"
          ],
          "pattern": "^-?[0-9]+(\\.[0-9]+)?$",
          "description": "Exact decimal string. Never rounded for transport. Null means unreadable, not zero."
        },
        "spotPrice": {
          "type": [
            "string",
            "null"
          ],
          "pattern": "^-?[0-9]+(\\.[0-9]+)?$",
          "description": "Exact decimal string. Never rounded for transport. Null means unreadable, not zero."
        },
        "effectivePrice": {
          "type": [
            "string",
            "null"
          ],
          "pattern": "^-?[0-9]+(\\.[0-9]+)?$",
          "description": "Exact decimal string. Never rounded for transport. Null means unreadable, not zero."
        },
        "priceImpactPct": {
          "type": [
            "string",
            "null"
          ],
          "pattern": "^-?[0-9]+(\\.[0-9]+)?$",
          "description": "Exact decimal string. Never rounded for transport. Null means unreadable, not zero."
        },
        "poolUtilisationPct": {
          "type": [
            "string",
            "null"
          ],
          "pattern": "^-?[0-9]+(\\.[0-9]+)?$",
          "description": "Exact decimal string. Never rounded for transport. Null means unreadable, not zero."
        },
        "poolInAfter": {
          "type": [
            "string",
            "null"
          ],
          "pattern": "^-?[0-9]+(\\.[0-9]+)?$",
          "description": "Exact decimal string. Never rounded for transport. Null means unreadable, not zero."
        },
        "poolOutAfter": {
          "type": [
            "string",
            "null"
          ],
          "pattern": "^-?[0-9]+(\\.[0-9]+)?$",
          "description": "Exact decimal string. Never rounded for transport. Null means unreadable, not zero."
        },
        "slippageTolerancePct": {
          "type": [
            "string",
            "null"
          ],
          "pattern": "^-?[0-9]+(\\.[0-9]+)?$",
          "description": "Exact decimal string. Never rounded for transport. Null means unreadable, not zero."
        },
        "minimumReceived": {
          "type": [
            "string",
            "null"
          ],
          "pattern": "^-?[0-9]+(\\.[0-9]+)?$",
          "description": "Exact decimal string. Never rounded for transport. Null means unreadable, not zero."
        },
        "maximumPaid": {
          "type": [
            "string",
            "null"
          ],
          "pattern": "^-?[0-9]+(\\.[0-9]+)?$",
          "description": "Exact decimal string. Never rounded for transport. Null means unreadable, not zero."
        }
      }
    }
  }
}