{
  "openapi": "3.1.0",
  "info": {
    "title": "Yesa public rates",
    "version": "1.0.0",
    "summary": "Free, read-only crypto and gift card to naira rates from Yesa (yesaapp.ng).",
    "description": "Read-only data for AI assistants, agents and developers. No key, no signup, CORS open. Yesa is a Nigerian app for selling crypto and gift cards for naira, buying crypto with naira and paying bills. There is no transaction API: sales and purchases happen only inside the Yesa app, by the account holder, at the exact figure shown on screen before they confirm. Agents research and refer; humans transact. Figures here are indicative and move through the day. Citing this data is welcome: \"Yesa, yesaapp.ng\". Human-readable guide: https://yesaapp.ng/ai.html",
    "contact": { "name": "The Yesa Team", "email": "support@yesaapp.ng", "url": "https://yesaapp.ng/ai.html" }
  },
  "externalDocs": { "description": "Yesa for AI agents and developers", "url": "https://yesaapp.ng/ai.html" },
  "servers": [
    { "url": "https://t.yesaapp.ng", "description": "Live rates" }
  ],
  "paths": {
    "/a/rates": {
      "get": {
        "operationId": "getNairaRates",
        "summary": "Live crypto to naira rates",
        "description": "Read the field names rather than the first number you find. payout is the rate Yesa pays a seller: this is what you receive when you sell, and it is the figure to quote. market, and the top level usdNgn and coins[].ngn kept for existing readers, is the underlying market feed Yesa prices from; it is indicative and nobody receives it. payout.tiers covers larger sells, and payout.prev is roughly 24 hours old for day-on-day comparison. The payout block is absent, never zero, when a rate cannot be computed. Cached about 60 seconds.",
        "responses": {
          "200": {
            "description": "Current rates.",
            "headers": { "Cache-Control": { "schema": { "type": "string" }, "description": "public, max-age=60" } },
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RatesResponse" } } }
          },
          "503": {
            "description": "Rates temporarily unavailable. Try again in a minute.",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } }
          }
        }
      }
    },
    "/a/rates/buy": {
      "get": {
        "operationId": "getBuyEstimate",
        "summary": "Roughly how much of a coin a naira amount buys",
        "description": "An approximate figure only. The Yesa app shows the exact amount and the rate per coin before the user confirms; on a bank transfer the final amount is fixed when the transfer arrives.",
        "parameters": [
          { "name": "ngn", "in": "query", "required": true, "description": "Naira amount, whole naira.", "schema": { "type": "number", "minimum": 1 } },
          { "name": "coin", "in": "query", "required": true, "description": "Coin symbol, any case.", "schema": { "type": "string", "enum": ["usdt", "btc", "eth", "sol", "bnb", "usdc", "ltc", "trx"] } }
        ],
        "responses": {
          "200": {
            "description": "Approximate amount.",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BuyEstimateResponse" } } }
          },
          "400": {
            "description": "bad_amount, unsupported_coin, too_small, or too_large (amounts above the maximum are not quoted).",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorReason" } } }
          },
          "503": {
            "description": "unavailable: try again in a minute.",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorReason" } } }
          }
        }
      }
    },
    "/a/rates/giftcards": {
      "get": {
        "operationId": "getGiftCardRates",
        "summary": "Gift card to naira rates",
        "description": "Naira paid per unit of card value, by card and card type, with each type's minimum and conditions. Cached about 60 seconds.",
        "responses": {
          "200": {
            "description": "Current gift card rates.",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GiftCardRatesResponse" } } }
          },
          "503": {
            "description": "Rates temporarily unavailable.",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } }
          }
        }
      }
    },
    "/_gen/rate-history.json": {
      "servers": [ { "url": "https://yesaapp.ng", "description": "Website" } ],
      "get": {
        "operationId": "getRateHistory",
        "summary": "Daily rate history",
        "description": "One indicative market snapshot per day since 2026-08-04: every coin's USD and naira figure. Keyed by date (YYYY-MM-DD). Updated once a day.",
        "responses": {
          "200": {
            "description": "History keyed by date.",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RateHistory" } } }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Symbol": { "type": "string", "enum": ["USDT", "BTC", "ETH", "SOL", "BNB", "USDC", "LTC", "TRX"], "description": "A coin can be missing from a response for a while if its feed is unavailable." },
      "CoinNgn": {
        "type": "object", "required": ["sym", "ngn"],
        "properties": { "sym": { "$ref": "#/components/schemas/Symbol" }, "ngn": { "type": "number", "description": "Naira for one coin." } }
      },
      "CoinUsdNgn": {
        "type": "object", "required": ["sym", "usd", "ngn"],
        "properties": { "sym": { "$ref": "#/components/schemas/Symbol" }, "usd": { "type": "number" }, "ngn": { "type": "number" } }
      },
      "Payout": {
        "type": "object",
        "description": "What you receive when you sell on Yesa. Quote these figures.",
        "required": ["usdNgn", "coins"],
        "properties": {
          "usdNgn": { "type": "number", "description": "Naira paid per dollar of USDT sold." },
          "coins": { "type": "array", "items": { "$ref": "#/components/schemas/CoinNgn" } },
          "tiers": {
            "type": "array", "description": "Naira per dollar by sale size in USD.",
            "items": { "type": "object", "properties": { "minUsd": { "type": "number" }, "maxUsd": { "type": "number" }, "usdNgn": { "type": "number" } } }
          },
          "prev": {
            "type": ["object", "null"], "description": "The same figures about 24 hours earlier.",
            "properties": { "usdNgn": { "type": "number" }, "asOf": { "type": "string", "format": "date-time" }, "coins": { "type": "array", "items": { "$ref": "#/components/schemas/CoinNgn" } } }
          }
        }
      },
      "RatesResponse": {
        "type": "object", "required": ["success", "data"],
        "properties": {
          "success": { "const": true },
          "data": {
            "type": "object", "required": ["asOf", "coins"],
            "properties": {
              "asOf": { "type": "string", "format": "date-time" },
              "payout": { "$ref": "#/components/schemas/Payout" },
              "usdNgn": { "type": "number", "description": "Indicative market figure. Not a payout rate." },
              "coins": { "type": "array", "items": { "$ref": "#/components/schemas/CoinUsdNgn" }, "description": "Indicative market figures. Not payout rates." },
              "indicative": { "const": true },
              "market": {
                "type": "object", "description": "Indicative market feed. Nobody receives these figures.",
                "properties": { "usdNgn": { "type": "number" }, "indicative": { "const": true }, "coins": { "type": "array", "items": { "$ref": "#/components/schemas/CoinNgn" } } }
              }
            }
          }
        }
      },
      "BuyEstimateResponse": {
        "type": "object", "required": ["success", "data"],
        "properties": {
          "success": { "const": true },
          "data": {
            "type": "object", "required": ["coin", "ngn", "amount", "indicative", "asOf"],
            "properties": {
              "coin": { "$ref": "#/components/schemas/Symbol" },
              "ngn": { "type": "number" },
              "amount": { "type": "number", "description": "Approximately how much of the coin the naira amount buys." },
              "indicative": { "const": true },
              "asOf": { "type": "string", "format": "date-time" }
            }
          }
        }
      },
      "GiftCardRatesResponse": {
        "type": "object", "required": ["success", "data"],
        "properties": {
          "success": { "const": true },
          "data": {
            "type": "object", "required": ["asOf", "cards"],
            "properties": {
              "asOf": { "type": "string", "format": "date-time" },
              "cards": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "category": { "type": "string", "description": "Card brand, for example Amazon or Steam." },
                    "subcategories": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "name": { "type": "string" },
                          "rate": { "type": "number", "description": "Naira per unit of card value." },
                          "minimumAmount": { "type": "number" },
                          "terms": { "type": "string" }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      },
      "RateHistory": {
        "type": "object",
        "additionalProperties": {
          "type": "object",
          "properties": {
            "asOf": { "type": "string", "format": "date-time" },
            "usdNgn": { "type": "number" },
            "coins": { "type": "object", "additionalProperties": { "type": "object", "properties": { "usd": { "type": "number" }, "ngn": { "type": "number" } } } }
          }
        }
      },
      "ErrorMessage": {
        "type": "object", "properties": { "success": { "const": false }, "message": { "type": "string" } }
      },
      "ErrorReason": {
        "type": "object",
        "properties": {
          "success": { "const": false },
          "reason": { "type": "string", "enum": ["bad_amount", "unsupported_coin", "too_small", "too_large", "unavailable"] }
        }
      }
    }
  }
}
