{
  "openapi": "3.1.0",
  "info": {
    "title": "Indexa Exchange Rates API",
    "version": "1.0.0",
    "description": "Qualified Dominican exchange-rate observations. Buy and sell are always from the provider's perspective."
  },
  "components": {
    "schemas": {}
  },
  "paths": {
    "/v1/exchange-rate-providers": {
      "get": {
        "operationId": "listExchangeRateProviders",
        "summary": "List exchange-rate providers",
        "tags": [
          "Exchange rates"
        ],
        "description": "List providers and qualified source coverage.",
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "providers"
                  ],
                  "properties": {
                    "providers": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "id",
                          "name",
                          "supportedSeries",
                          "sources"
                        ],
                        "properties": {
                          "id": {
                            "type": "string",
                            "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$"
                          },
                          "name": {
                            "type": "string",
                            "minLength": 1
                          },
                          "supportedSeries": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "required": [
                                "baseCurrency",
                                "quoteCurrency",
                                "channel"
                              ],
                              "properties": {
                                "baseCurrency": {
                                  "type": "string",
                                  "pattern": "^[A-Z]{3}$"
                                },
                                "quoteCurrency": {
                                  "type": "string",
                                  "pattern": "^[A-Z]{3}$"
                                },
                                "channel": {
                                  "anyOf": [
                                    {
                                      "type": "string",
                                      "enum": [
                                        "office"
                                      ]
                                    },
                                    {
                                      "type": "string",
                                      "enum": [
                                        "online"
                                      ]
                                    },
                                    {
                                      "type": "string",
                                      "enum": [
                                        "unspecified"
                                      ]
                                    }
                                  ]
                                }
                              },
                              "additionalProperties": false
                            }
                          },
                          "sources": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "required": [
                                "id",
                                "name",
                                "kind",
                                "currentAvailable",
                                "historicalAvailable"
                              ],
                              "properties": {
                                "id": {
                                  "type": "string",
                                  "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$"
                                },
                                "name": {
                                  "type": "string",
                                  "minLength": 1
                                },
                                "kind": {
                                  "anyOf": [
                                    {
                                      "type": "string",
                                      "enum": [
                                        "direct"
                                      ]
                                    },
                                    {
                                      "type": "string",
                                      "enum": [
                                        "secondary"
                                      ]
                                    },
                                    {
                                      "type": "string",
                                      "enum": [
                                        "legacy"
                                      ]
                                    }
                                  ]
                                },
                                "currentAvailable": {
                                  "type": "boolean"
                                },
                                "historicalAvailable": {
                                  "type": "boolean"
                                }
                              },
                              "additionalProperties": false
                            }
                          }
                        },
                        "additionalProperties": false
                      }
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "503": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message",
                        "requestId",
                        "retryable"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "minLength": 1
                        },
                        "message": {
                          "type": "string",
                          "minLength": 1
                        },
                        "requestId": {
                          "type": "string",
                          "minLength": 1
                        },
                        "retryable": {
                          "type": "boolean"
                        }
                      },
                      "additionalProperties": false
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          }
        }
      }
    },
    "/v1/exchange-rates": {
      "get": {
        "operationId": "getLatestExchangeRates",
        "summary": "Get latest exchange rates",
        "tags": [
          "Exchange rates"
        ],
        "description": "Return fresh qualified quotes. Secondary sources are considered only with allowSecondary=true.",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "query",
            "name": "provider",
            "required": false
          },
          {
            "schema": {
              "type": "string"
            },
            "in": "query",
            "name": "base",
            "required": false
          },
          {
            "schema": {
              "type": "string"
            },
            "in": "query",
            "name": "quote",
            "required": false
          },
          {
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "enum": [
                    "office"
                  ]
                },
                {
                  "type": "string",
                  "enum": [
                    "online"
                  ]
                },
                {
                  "type": "string",
                  "enum": [
                    "unspecified"
                  ]
                }
              ]
            },
            "in": "query",
            "name": "channel",
            "required": false
          },
          {
            "schema": {
              "type": "string"
            },
            "in": "query",
            "name": "allowSecondary",
            "required": false
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "rates",
                    "unavailable"
                  ],
                  "properties": {
                    "rates": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "provider",
                          "baseCurrency",
                          "quoteCurrency",
                          "channel",
                          "buy",
                          "sell",
                          "source",
                          "sourceKind",
                          "observationDate",
                          "observedAt",
                          "retrievedAt"
                        ],
                        "properties": {
                          "provider": {
                            "type": "string",
                            "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$"
                          },
                          "baseCurrency": {
                            "type": "string",
                            "pattern": "^[A-Z]{3}$"
                          },
                          "quoteCurrency": {
                            "type": "string",
                            "pattern": "^[A-Z]{3}$"
                          },
                          "channel": {
                            "anyOf": [
                              {
                                "type": "string",
                                "enum": [
                                  "office"
                                ]
                              },
                              {
                                "type": "string",
                                "enum": [
                                  "online"
                                ]
                              },
                              {
                                "type": "string",
                                "enum": [
                                  "unspecified"
                                ]
                              }
                            ]
                          },
                          "buy": {
                            "anyOf": [
                              {
                                "type": "string",
                                "pattern": "^[0-9]+(?:\\.[0-9]+)?$"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "sell": {
                            "anyOf": [
                              {
                                "type": "string",
                                "pattern": "^[0-9]+(?:\\.[0-9]+)?$"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "source": {
                            "type": "string",
                            "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$"
                          },
                          "sourceKind": {
                            "anyOf": [
                              {
                                "type": "string",
                                "enum": [
                                  "direct"
                                ]
                              },
                              {
                                "type": "string",
                                "enum": [
                                  "secondary"
                                ]
                              },
                              {
                                "type": "string",
                                "enum": [
                                  "legacy"
                                ]
                              }
                            ]
                          },
                          "observationDate": {
                            "type": "string",
                            "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
                          },
                          "observedAt": {
                            "anyOf": [
                              {
                                "type": "string",
                                "format": "date-time"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "retrievedAt": {
                            "anyOf": [
                              {
                                "type": "string",
                                "format": "date-time"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "unavailable": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "provider",
                          "baseCurrency",
                          "quoteCurrency",
                          "channel",
                          "reason"
                        ],
                        "properties": {
                          "provider": {
                            "type": "string",
                            "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$"
                          },
                          "baseCurrency": {
                            "type": "string",
                            "pattern": "^[A-Z]{3}$"
                          },
                          "quoteCurrency": {
                            "type": "string",
                            "pattern": "^[A-Z]{3}$"
                          },
                          "channel": {
                            "anyOf": [
                              {
                                "type": "string",
                                "enum": [
                                  "office"
                                ]
                              },
                              {
                                "type": "string",
                                "enum": [
                                  "online"
                                ]
                              },
                              {
                                "type": "string",
                                "enum": [
                                  "unspecified"
                                ]
                              }
                            ]
                          },
                          "reason": {
                            "anyOf": [
                              {
                                "type": "string",
                                "enum": [
                                  "stale"
                                ]
                              },
                              {
                                "type": "string",
                                "enum": [
                                  "unavailable"
                                ]
                              }
                            ]
                          }
                        },
                        "additionalProperties": false
                      }
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message",
                        "requestId",
                        "retryable"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "minLength": 1
                        },
                        "message": {
                          "type": "string",
                          "minLength": 1
                        },
                        "requestId": {
                          "type": "string",
                          "minLength": 1
                        },
                        "retryable": {
                          "type": "boolean"
                        }
                      },
                      "additionalProperties": false
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message",
                        "requestId",
                        "retryable"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "minLength": 1
                        },
                        "message": {
                          "type": "string",
                          "minLength": 1
                        },
                        "requestId": {
                          "type": "string",
                          "minLength": 1
                        },
                        "retryable": {
                          "type": "boolean"
                        }
                      },
                      "additionalProperties": false
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "503": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message",
                        "requestId",
                        "retryable"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "minLength": 1
                        },
                        "message": {
                          "type": "string",
                          "minLength": 1
                        },
                        "requestId": {
                          "type": "string",
                          "minLength": 1
                        },
                        "retryable": {
                          "type": "boolean"
                        }
                      },
                      "additionalProperties": false
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          }
        }
      }
    },
    "/v1/exchange-rates/history": {
      "get": {
        "operationId": "getExchangeRateHistory",
        "summary": "Get exchange-rate history",
        "tags": [
          "Exchange rates"
        ],
        "description": "Return captured qualified changes. Empty intervals do not prove that a provider's prices were unchanged.",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "query",
            "name": "provider",
            "required": true
          },
          {
            "schema": {
              "type": "string"
            },
            "in": "query",
            "name": "base",
            "required": false
          },
          {
            "schema": {
              "type": "string"
            },
            "in": "query",
            "name": "quote",
            "required": false
          },
          {
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "enum": [
                    "office"
                  ]
                },
                {
                  "type": "string",
                  "enum": [
                    "online"
                  ]
                },
                {
                  "type": "string",
                  "enum": [
                    "unspecified"
                  ]
                }
              ]
            },
            "in": "query",
            "name": "channel",
            "required": false
          },
          {
            "schema": {
              "type": "string"
            },
            "in": "query",
            "name": "source",
            "required": false
          },
          {
            "schema": {
              "type": "string"
            },
            "in": "query",
            "name": "from",
            "required": false
          },
          {
            "schema": {
              "type": "string"
            },
            "in": "query",
            "name": "to",
            "required": false
          },
          {
            "schema": {
              "type": "string"
            },
            "in": "query",
            "name": "limit",
            "required": false
          },
          {
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]+$"
            },
            "in": "query",
            "name": "cursor",
            "required": false
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "observations",
                    "nextCursor"
                  ],
                  "properties": {
                    "observations": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "provider",
                          "baseCurrency",
                          "quoteCurrency",
                          "channel",
                          "buy",
                          "sell",
                          "source",
                          "sourceKind",
                          "observationDate",
                          "observedAt",
                          "retrievedAt"
                        ],
                        "properties": {
                          "provider": {
                            "type": "string",
                            "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$"
                          },
                          "baseCurrency": {
                            "type": "string",
                            "pattern": "^[A-Z]{3}$"
                          },
                          "quoteCurrency": {
                            "type": "string",
                            "pattern": "^[A-Z]{3}$"
                          },
                          "channel": {
                            "anyOf": [
                              {
                                "type": "string",
                                "enum": [
                                  "office"
                                ]
                              },
                              {
                                "type": "string",
                                "enum": [
                                  "online"
                                ]
                              },
                              {
                                "type": "string",
                                "enum": [
                                  "unspecified"
                                ]
                              }
                            ]
                          },
                          "buy": {
                            "anyOf": [
                              {
                                "type": "string",
                                "pattern": "^[0-9]+(?:\\.[0-9]+)?$"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "sell": {
                            "anyOf": [
                              {
                                "type": "string",
                                "pattern": "^[0-9]+(?:\\.[0-9]+)?$"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "source": {
                            "type": "string",
                            "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$"
                          },
                          "sourceKind": {
                            "anyOf": [
                              {
                                "type": "string",
                                "enum": [
                                  "direct"
                                ]
                              },
                              {
                                "type": "string",
                                "enum": [
                                  "secondary"
                                ]
                              },
                              {
                                "type": "string",
                                "enum": [
                                  "legacy"
                                ]
                              }
                            ]
                          },
                          "observationDate": {
                            "type": "string",
                            "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
                          },
                          "observedAt": {
                            "anyOf": [
                              {
                                "type": "string",
                                "format": "date-time"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "retrievedAt": {
                            "anyOf": [
                              {
                                "type": "string",
                                "format": "date-time"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "nextCursor": {
                      "anyOf": [
                        {
                          "type": "string",
                          "pattern": "^[A-Za-z0-9_-]+$"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message",
                        "requestId",
                        "retryable"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "minLength": 1
                        },
                        "message": {
                          "type": "string",
                          "minLength": 1
                        },
                        "requestId": {
                          "type": "string",
                          "minLength": 1
                        },
                        "retryable": {
                          "type": "boolean"
                        }
                      },
                      "additionalProperties": false
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message",
                        "requestId",
                        "retryable"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "minLength": 1
                        },
                        "message": {
                          "type": "string",
                          "minLength": 1
                        },
                        "requestId": {
                          "type": "string",
                          "minLength": 1
                        },
                        "retryable": {
                          "type": "boolean"
                        }
                      },
                      "additionalProperties": false
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "503": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message",
                        "requestId",
                        "retryable"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "minLength": 1
                        },
                        "message": {
                          "type": "string",
                          "minLength": 1
                        },
                        "requestId": {
                          "type": "string",
                          "minLength": 1
                        },
                        "retryable": {
                          "type": "boolean"
                        }
                      },
                      "additionalProperties": false
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          }
        }
      }
    }
  },
  "servers": [
    {
      "url": "/"
    }
  ],
  "security": [],
  "tags": [
    {
      "name": "Exchange rates",
      "description": "Qualified Dominican exchange-rate providers, latest quotes, and history."
    }
  ]
}