---
title: "BNM MYR exchange-rate fixing panel"
method: GET
path: "/api/v1/bnm/exchange-rate"
tags: ["Central Banks & Monetary"]
---

# BNM MYR exchange-rate fixing panel

`GET /api/v1/bnm/exchange-rate`

BNM MYR exchange-rate fixing across 27 currencies. Four daily sessions: `0900` Interbank Intervention Rate (USD-only pair), `1130` Best Counter Rate (majors only), `1200` Reference Rate (27 currencies), `1700` Reference Rate closing (default, 27 currencies). The `quote` param toggles quote direction: `rm` (default, MYR per unit foreign currency) or `fc` (foreign currency per MYR). Units vary per currency (1 for major currencies, 100 for minor / high-denomination currencies such as JPY, IDR, VND, KHR, NPR); the response exposes both the raw per-unit rate and a normalised `per_unit_*` trio.

## Query parameters

- `session` string, nullable — Optional session identifier. One of `0900`, `1130`, `1200`, `1700`. Default upstream: `1700`.
- `quote` string, nullable — Optional quote direction. `rm` = MYR per unit foreign currency (default). `fc` = foreign currency per MYR.
- `currency` string, nullable — Optional ISO 4217 currency code filter (e.g. USD, EUR). Filtering is applied client-side.

## Response `200`

27-currency panel for the requested session with buying/selling/middle rates.

- EnvelopeBnmExchangeRatePayload
  - `data` BnmExchangeRatePayload, required
    - `session` string, nullable — BNM session identifier as a string with leading zeros preserved: `0900`, `1130`, `1200`, or `1700`.
    - `quote` string, nullable — Quote direction: `rm` = MYR per foreign currency, `fc` = foreign currency per MYR.
    - `count` integer, required — Number of currency rows returned.
    - `rates` BnmExchangeRateRow[], required — Per-currency rate rows. Up to 27 currencies; filtered when the `currency` query is set.
      - `currency_code` string, nullable — Currency ISO 4217 code (e.g. USD, EUR, JPY, SGD).
      - `unit` integer, required — Quotation unit as published by BNM (1 for major currencies, 100 for minor / high-denomination currencies such as IDR, JPY, VND, KHR, NPR). The raw rate is per `unit` foreign currency units.
      - `date` string, nullable — Quote date (YYYY-MM-DD).
      - `buying_rate` number, nullable — BNM buying rate for `unit` foreign currency units, in MYR (for quote=rm) or per MYR (for quote=fc).
      - `selling_rate` number, nullable — BNM selling rate for `unit` foreign currency units.
      - `middle_rate` number, nullable — BNM middle rate for `unit` foreign currency units.
      - `per_unit_buying_rate` number, nullable — Buying rate normalised to one (1) foreign currency unit (= buying_rate / unit).
      - `per_unit_selling_rate` number, nullable — Selling rate normalised to one (1) foreign currency unit.
      - `per_unit_middle_rate` number, nullable — Middle rate normalised to one (1) foreign currency unit.
  - `meta` SugraMeta, required — Metadata attached to every /api/v1/* response envelope.
    - `endpoint` string, required — Requested endpoint path.
    - `data_time` string, required — ISO 8601 UTC timestamp of the source data, not of the request.
    - `response_time` string, required — ISO 8601 UTC timestamp when this response was produced.
    - `provider` string, required — API name and version.
    - `source` string, nullable — Identifier of the primary upstream source used for this response.
    - `attribution` string, nullable — Human-readable attribution mandated by an upstream source (e.g. a securities regulator or self-regulatory organization). Present only on responses whose source requires the owner and source to be clearly identified. Do not remove or alter it when using the response.
    - `fallback_used` boolean, nullable — True when the primary source failed and a fallback produced the data.
    - `fallback_chain` string[], nullable — Ordered list of sources attempted, in the order they were tried.
    - `cached` boolean, nullable — True when this response was served from the internal cache.
    - `stale` boolean, nullable — True when the cached response was returned after the upstream rate-limited or errored. Clients can use this to detect degraded data.

## Other responses

- `401` — Missing or invalid `x-api-key` header. JSON body with a stable `code` distinguishing `missing_api_key` (no header sent) from `invalid_api_key` (header sent, key not accepted); any other 401 source carries the generic `unauthorized` with its detail as `reason`. Plus `hint`. `plan` is always null on 401 - an unauthenticated request has no plan; quota exhaustion is 429, not 401.
- `422` — Validation Error
- `429` — Daily rate limit exceeded. Check `X-RateLimit-Reset` for the next window.
- `503` — Upstream source is temporarily unavailable. Retry after a short delay.

---

[API](https://skmtc.net/sugra/apis/sugra-api.md) · [All operations](https://skmtc.net/sugra/apis/sugra-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/sugra/sugra-api/versions/d3e3d9c28132/schema)
