{
  "openapi": "3.1.0",
  "info": {
    "title": "Mehr Rates API",
    "version": "1.0.0",
    "description": "High-performance, zero-auth public REST API for real-time Iranian free-market foreign exchange, sovereign mint coins, bullion benchmarks, global fiat cross-rates, and major spot cryptocurrencies. Backed by Cloudflare Workers V8 edge caching with native ETag & HTTP 304 support.",
    "contact": {
      "name": "Mehrnet API Support",
      "url": "https://rates.mehrnet.com/#api"
    },
    "license": {
      "name": "MIT",
      "url": "https://opensource.org/licenses/MIT"
    }
  },
  "servers": [
    {
      "url": "https://rates-api.mehrnet.com",
      "description": "Global Anycast Edge Network (Cloudflare Workers)"
    }
  ],
  "tags": [
    {
      "name": "Rates",
      "description": "Real-time spot exchange rates, filtered market sheets, and cross-currency conversions"
    },
    {
      "name": "Historical",
      "description": "Calendar day closing rate sheets and high-resolution time-series price data"
    },
    {
      "name": "Providers & Telemetry",
      "description": "Fleet scraper health, operational sync cadences, and execution audit logs"
    },
    {
      "name": "System",
      "description": "Heartbeat health probes and OpenAPI schema definitions"
    }
  ],
  "paths": {
    "/historical": {
      "get": {
        "tags": [
          "Historical"
        ],
        "summary": "Historical calendar rate sheet lookup",
        "description": "Returns the official daily closing rate sheet for any past calendar date (YYYY-MM-DD) across all 1,970 tracked assets.",
        "operationId": "getHistoricalRates",
        "parameters": [
          {
            "name": "date",
            "in": "query",
            "required": true,
            "description": "Target historical date in `YYYY-MM-DD` format (e.g. `2026-08-14`).",
            "schema": {
              "type": "string",
              "format": "date",
              "example": "2026-08-14"
            }
          },
          {
            "name": "symbols",
            "in": "query",
            "required": false,
            "description": "Comma-separated list of symbols to filter (e.g. `USD,EUR,BTC,EMAMI`).",
            "schema": {
              "type": "string",
              "example": "USD,EUR,BTC,EMAMI"
            }
          },
          {
            "name": "category",
            "in": "query",
            "required": false,
            "description": "Filter by asset class (`market`, `coins`, `gold`, `fiat`, `crypto`).",
            "schema": {
              "type": "string",
              "enum": [
                "market",
                "coins",
                "gold",
                "fiat",
                "crypto"
              ],
              "example": "market"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Historical rate sheet successfully returned.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UnifiedRateSheet"
                }
              }
            }
          },
          "404": {
            "description": "No historical rate sheet found for the given date.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/timeseries": {
      "get": {
        "tags": [
          "Historical"
        ],
        "summary": "Time-series historical data points for charts & sparklines",
        "description": "Streams chronological price points for any single asset across 15-minute, 1-hour, or 1-day intervals.",
        "operationId": "getTimeSeries",
        "parameters": [
          {
            "name": "symbol",
            "in": "query",
            "required": true,
            "description": "Asset ticker symbol (e.g. `USD`, `EUR`, `BTC`, `ETH`, `EMAMI`, `GOLD_18K`).",
            "schema": {
              "type": "string",
              "example": "USD"
            }
          },
          {
            "name": "days",
            "in": "query",
            "required": false,
            "description": "Time range in days (1 to 365, default 7).",
            "schema": {
              "type": "integer",
              "default": 7,
              "example": 7
            }
          },
          {
            "name": "interval",
            "in": "query",
            "required": false,
            "description": "Sampling frequency (`15m` for intraday, `1h` for standard, `1d` for macro, or `auto`).",
            "schema": {
              "type": "string",
              "enum": [
                "auto",
                "15m",
                "1h",
                "1d"
              ],
              "default": "auto"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum number of points to return (default 500).",
            "schema": {
              "type": "integer",
              "default": 500
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Time-series points array.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "symbol": {
                      "type": "string",
                      "example": "USD"
                    },
                    "interval": {
                      "type": "string",
                      "example": "1h"
                    },
                    "days": {
                      "type": "integer",
                      "example": 7
                    },
                    "total_points": {
                      "type": "integer",
                      "example": 168
                    },
                    "points": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "timestamp": {
                            "type": "integer",
                            "example": 1786718400000
                          },
                          "date_iso": {
                            "type": "string",
                            "format": "date-time",
                            "example": "2026-08-14T14:40:00.000Z"
                          },
                          "price": {
                            "type": "number",
                            "example": 187300
                          },
                          "buy": {
                            "type": "number",
                            "example": 186192
                          },
                          "sell": {
                            "type": "number",
                            "example": 187300
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/latest": {
      "get": {
        "tags": [
          "Rates"
        ],
        "summary": "Consolidated real-time market rate sheet",
        "description": "Returns full or filtered market state across free-market currencies (USD, EUR, AED in Tomans), sovereign gold coins (Emami, Azadi), bullion benchmarks (18K gold, Mithqal, Ounce), global fiat forex, and cryptocurrency spot prices.",
        "operationId": "getLatestRates",
        "parameters": [
          {
            "name": "symbols",
            "in": "query",
            "description": "Comma-separated list of asset ticker symbols to filter the response down to ~0.8 KB (e.g. `USD,EUR,BTC,ETH,EMAMI,GOLD_18K`).",
            "required": false,
            "schema": {
              "type": "string",
              "example": "USD,EUR,BTC,ETH,EMAMI,GOLD_18K"
            }
          },
          {
            "name": "category",
            "in": "query",
            "description": "Filter payload by an entire asset class.",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "market",
                "coins",
                "gold",
                "fiat",
                "crypto"
              ],
              "example": "market"
            }
          },
          {
            "name": "limit_crypto",
            "in": "query",
            "description": "Limit crypto dictionary to the top N major market-cap tokens.",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 250,
              "example": 50
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Consolidated rate sheet successfully returned.",
            "headers": {
              "ETag": {
                "description": "HTTP entity tag based on latest scrape epoch timestamp for zero-bandwidth cache revalidation.",
                "schema": {
                  "type": "string"
                }
              },
              "Cache-Control": {
                "description": "Public edge caching directives.",
                "schema": {
                  "type": "string",
                  "example": "public, max-age=15, s-maxage=30, stale-while-revalidate=60"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UnifiedRateSheet"
                }
              }
            }
          },
          "304": {
            "description": "Not Modified. Payload has not changed since the timestamp supplied in the `If-None-Match` header."
          }
        }
      }
    },
    "/rate/{symbol}": {
      "get": {
        "tags": [
          "Rates"
        ],
        "summary": "Single asset rate lookup",
        "description": "Retrieves valuation, buy/sell spreads, and Toman conversions for a specific fiat currency, crypto token, or gold coin.",
        "operationId": "getSingleRate",
        "parameters": [
          {
            "name": "symbol",
            "in": "path",
            "required": true,
            "description": "Asset ticker symbol (case-insensitive, e.g. `USD`, `EUR`, `BTC`, `ETH`, `EMAMI`, `GOLD_18K`).",
            "schema": {
              "type": "string",
              "example": "usd"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Asset valuation successfully returned.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SingleRateResponse"
                }
              }
            }
          },
          "404": {
            "description": "Asset symbol not recognized.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/rate": {
      "get": {
        "tags": [
          "Rates"
        ],
        "summary": "Cross-pair conversion calculator",
        "description": "Dynamically calculates direct exchange rates, inverse rates, and total converted amounts between any two global currencies, cryptos, or Tomans.",
        "operationId": "getCrossPairConversion",
        "parameters": [
          {
            "name": "pair",
            "in": "query",
            "required": true,
            "description": "Target cross pair in `BASE/TARGET` format (e.g. `EUR/USD`, `BTC/EUR`, `USD/IRT`).",
            "schema": {
              "type": "string",
              "example": "EUR/USD"
            }
          },
          {
            "name": "amount",
            "in": "query",
            "required": false,
            "description": "Numeric amount of base currency to convert.",
            "schema": {
              "type": "number",
              "default": 1,
              "example": 100
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Calculated conversion result.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CrossPairResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid or unsupported pair format.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/providers": {
      "get": {
        "tags": [
          "Providers & Telemetry"
        ],
        "summary": "Fleet provider registry and sync statuses",
        "description": "Returns health status, active polling cadences, and last sync times across all first-party scrapers (Bonbast, Navasan, TGJU, Arzbin, Binance, Coinbase, OpenER, etc.).",
        "operationId": "getProviders",
        "responses": {
          "200": {
            "description": "Provider registry list.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProvidersResponse"
                }
              }
            }
          }
        }
      }
    },
    "/logs": {
      "get": {
        "tags": [
          "Providers & Telemetry"
        ],
        "summary": "Real-time scraper execution and audit logs",
        "description": "Streams recent execution traces, duration measurements, proxy failovers, and HTTP status codes recorded across all scrapers.",
        "operationId": "getLogs",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Number of log records to return (1-100).",
            "schema": {
              "type": "integer",
              "default": 50,
              "example": 5
            }
          },
          {
            "name": "provider",
            "in": "query",
            "required": false,
            "description": "Filter logs by provider identifier (e.g. `bonbast`, `binance`, `tgju`).",
            "schema": {
              "type": "string",
              "example": "bonbast"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "Pagination page number.",
            "schema": {
              "type": "integer",
              "default": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Telemetry log records.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LogsResponse"
                }
              }
            }
          }
        }
      }
    },
    "/health": {
      "get": {
        "tags": [
          "System"
        ],
        "summary": "Service uptime and database health check",
        "description": "Liveness and readiness probe for load balancers and uptime monitoring.",
        "operationId": "getHealth",
        "responses": {
          "200": {
            "description": "Service is operational.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "example": "ok"
                    },
                    "service": {
                      "type": "string",
                      "example": "rates-api"
                    },
                    "uptime": {
                      "type": "boolean",
                      "example": true
                    },
                    "server_time": {
                      "type": "string",
                      "format": "date-time",
                      "example": "2026-08-14T13:05:02.228Z"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/openapi.json": {
      "get": {
        "tags": [
          "System"
        ],
        "summary": "OpenAPI 3.1.0 schema specification",
        "description": "Machine-readable OpenAPI 3.1 schema for API gateways, code generators, and Postman/Swagger import.",
        "operationId": "getOpenApiSpec",
        "responses": {
          "200": {
            "description": "OpenAPI 3.1 JSON document.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "UnifiedRateSheet": {
        "type": "object",
        "properties": {
          "timestamp": {
            "type": "integer",
            "example": 1786712702228
          },
          "date_iso": {
            "type": "string",
            "format": "date-time",
            "example": "2026-08-14T13:05:02.228Z"
          },
          "base": {
            "type": "string",
            "example": "IRT"
          },
          "currencies": {
            "type": "object",
            "additionalProperties": {
              "type": "object",
              "properties": {
                "buy": {
                  "type": "number",
                  "example": 186192
                },
                "sell": {
                  "type": "number",
                  "example": 187300
                }
              }
            }
          },
          "coins": {
            "type": "object",
            "additionalProperties": {
              "type": "object",
              "properties": {
                "buy": {
                  "type": "number",
                  "example": 186500000
                },
                "sell": {
                  "type": "number",
                  "example": 189500000
                }
              }
            }
          },
          "gold": {
            "type": "object",
            "properties": {
              "GOLD_GRAM_18K": {
                "type": "number",
                "example": 19038275
              },
              "MITHQAL": {
                "type": "number",
                "example": 82470000
              },
              "OUNCE": {
                "type": "number",
                "example": 4374.9
              }
            }
          },
          "fiat": {
            "type": "object",
            "properties": {
              "base": {
                "type": "string",
                "example": "USD"
              },
              "rates": {
                "type": "object",
                "additionalProperties": {
                  "type": "number"
                }
              }
            }
          },
          "crypto": {
            "type": "object",
            "properties": {
              "base": {
                "type": "string",
                "example": "USD"
              },
              "rates": {
                "type": "object",
                "additionalProperties": {
                  "type": "number"
                }
              }
            }
          },
          "sources": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "example": "bonbast"
                },
                "age_seconds": {
                  "type": "integer",
                  "example": 4
                }
              }
            }
          }
        }
      },
      "SingleRateResponse": {
        "type": "object",
        "properties": {
          "symbol": {
            "type": "string",
            "example": "USD"
          },
          "category": {
            "type": "string",
            "example": "market"
          },
          "sell": {
            "type": "number",
            "example": 187300
          },
          "buy": {
            "type": "number",
            "example": 186192
          },
          "base": {
            "type": "string",
            "example": "IRT"
          },
          "timestamp": {
            "type": "integer",
            "example": 1786712702228
          },
          "date_iso": {
            "type": "string",
            "format": "date-time",
            "example": "2026-08-14T13:05:02.228Z"
          }
        }
      },
      "CrossPairResponse": {
        "type": "object",
        "properties": {
          "pair": {
            "type": "string",
            "example": "EUR/USD"
          },
          "base": {
            "type": "string",
            "example": "EUR"
          },
          "target": {
            "type": "string",
            "example": "USD"
          },
          "rate": {
            "type": "number",
            "example": 1.157
          },
          "inverse_rate": {
            "type": "number",
            "example": 0.864
          },
          "amount": {
            "type": "number",
            "example": 100
          },
          "converted_value": {
            "type": "number",
            "example": 115.7
          },
          "timestamp": {
            "type": "integer",
            "example": 1786712702228
          },
          "date_iso": {
            "type": "string",
            "format": "date-time",
            "example": "2026-08-14T13:05:02.228Z"
          }
        }
      },
      "ProvidersResponse": {
        "type": "object",
        "properties": {
          "providers": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "example": "bonbast"
                },
                "label": {
                  "type": "string",
                  "example": "Bonbast Live Rates"
                },
                "category": {
                  "type": "string",
                  "example": "iran_market"
                },
                "last_status": {
                  "type": "string",
                  "example": "OK"
                },
                "consecutive_errors": {
                  "type": "integer",
                  "example": 0
                },
                "last_synced_ago_seconds": {
                  "type": "integer",
                  "example": 6
                }
              }
            }
          },
          "timestamp": {
            "type": "integer",
            "example": 1786712702228
          }
        }
      },
      "LogsResponse": {
        "type": "object",
        "properties": {
          "page": {
            "type": "integer",
            "example": 1
          },
          "limit": {
            "type": "integer",
            "example": 5
          },
          "total": {
            "type": "integer",
            "example": 1420
          },
          "logs": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "integer",
                  "example": 2489
                },
                "provider_id": {
                  "type": "string",
                  "example": "bonbast"
                },
                "level": {
                  "type": "string",
                  "example": "INFO"
                },
                "message": {
                  "type": "string",
                  "example": "Scrape succeeded for Bonbast Live Rates"
                },
                "details": {
                  "type": "object"
                },
                "created_date": {
                  "type": "string",
                  "format": "date-time",
                  "example": "2026-08-14T13:05:02.228Z"
                }
              }
            }
          }
        }
      },
      "ErrorResponse": {
        "type": "object",
        "properties": {
          "error": {
            "type": "boolean",
            "example": true
          },
          "message": {
            "type": "string",
            "example": "Asset symbol not found"
          },
          "timestamp": {
            "type": "integer",
            "example": 1786712702228
          }
        }
      }
    },
    "headers": {
      "X-RateLimit-Limit": {
        "description": "Maximum allowed requests per sliding 60-second window per IP.",
        "schema": {
          "type": "string",
          "example": "120"
        }
      },
      "X-RateLimit-Remaining": {
        "description": "Number of remaining allowed requests in the current sliding window.",
        "schema": {
          "type": "string",
          "example": "119"
        }
      },
      "X-RateLimit-Reset": {
        "description": "Unix epoch timestamp in seconds when the current sliding rate limit window resets.",
        "schema": {
          "type": "string",
          "example": "1786718400"
        }
      }
    }
  }
}