Historical Bosnia and Herzegovina Convertible Mark (BAM) Prices - Daily Time Series for API Consumers
You need to chart and backfill Bosnia and Herzegovina Convertible Mark (BAM) prices on a daily basis, wire them into a dashboard or research pipeline, and keep the latest level cached for alerts. By the end of this guide you’ll query BAM with Indices-API, parse the response fields that matter, understand quote conventions, and lay out a dependable daily time-series workflow that copes with weekends and end-of-day constraints.
Goal and scope: daily BAM series you can ship
The concrete job here is to produce a normalized daily time series for BAM that you can:
- Render on charts and heatmaps.
- Backfill between start and end dates for studies.
- Use for alerts or conversions against USD.
We’ll focus on two endpoints you’ll actually wire up: latest (for a quick baseline and heartbeat monitoring) and time-series (for backfills and rolling daily updates). We’ll also cover practicalities like date handling, weekends, caching, and why you shouldn’t request end_date equal to today.
If you’re completely new to Indices-API, skim the Documentation and confirm symbol codes on the Symbols page before you put anything into production.
Symbols and quote conventions you’ll rely on
Responses for BAM include multiple helpful keys in the rates object, all quoted with base: USD in the examples below. That means rates are expressed relative to USD.
| Symbol in rates | Meaning when base is USD | Interpretation |
|---|---|---|
| BAM | Units of BAM per 1 USD | 1 USD = rates.BAM BAM |
| USDBAM | Units of USD per 1 BAM | 1 BAM = rates.USDBAM USD (inverse of rates.BAM) |
| USD | USD per 1 USD (identity) | Always 1 when base is USD |
Confirm BAM in the Indices-API Supported Symbols. If you need other regional currencies alongside BAM, use that page to verify their exact codes—don’t guess.
Quick test: curl the BAM latest and inspect fields
Use your API key in the access_key query parameter. We’ll hit the latest endpoint and show the exact JSON the service returns for BAM in this fixture, then discuss how to use its fields (timestamp, date, base, rates).
curl -s "https://indices-api.com/api/latest?access_key=YOUR_API_KEY&symbols=BAM,USDBAM,USD"
Official sample response (copy-pasteable for tests):
{"data":{"success":true,"timestamp":1792197600,"date":"2026-10-17","base":"USD","rates":{"BAM":1.742136,"USD":1,"USDBAM":0.5740079993754793}}}
What you’ll use from this payload
- data.success: Boolean flag you should check before reading values.
- data.timestamp: Unix time (seconds). Treat it as UTC and convert to your app’s timezone if needed.
- data.date: ISO-8601 YYYY-MM-DD for the effective rate date; daily endpoints align to this date.
- data.base: The quotation base. In this sample it’s USD, so rates are expressed vs. USD.
- data.rates.BAM: BAM per 1 USD. For the sample date, 1 USD = 1.742136 BAM.
- data.rates.USDBAM: USD per 1 BAM. For the sample date, 1 BAM ≈ 0.574008 USD (inverse of 1.742136).
- data.rates.USD: Identity rate, 1 when base is USD. Useful sanity check in pipelines.
Working code: Python snippet to fetch and parse BAM latest
This script calls the same latest endpoint as the curl above, checks success, and reads base, date, and the two-way USD↔BAM quotes you’ll chart or cache.
import os
import time
import requests
API_KEY = os.getenv("INDICES_API_KEY", "YOUR_API_KEY")
URL = "https://indices-api.com/api/latest"
params = {
"access_key": API_KEY,
"symbols": "BAM,USDBAM,USD"
}
resp = requests.get(URL, params=params, timeout=15)
resp.raise_for_status()
payload = resp.json()
if not payload.get("data", {}).get("success", False):
raise RuntimeError(f"API error or unsuccessful flag: {payload}")
data = payload["data"]
ts = data["timestamp"] # Unix seconds, UTC
as_of = data["date"] # YYYY-MM-DD
base = data["base"] # 'USD' in this sample
rates = data["rates"]
bam_per_usd = rates["BAM"] # e.g., 1.742136 BAM per 1 USD
usd_per_bam = rates["USDBAM"] # e.g., 0.574007999... USD per 1 BAM
print(f"as_of={as_of} ({time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime(ts))} UTC), base={base}")
print(f"1 USD = {bam_per_usd} BAM")
print(f"1 BAM = {usd_per_bam} USD")
# Example: normalize to a standard record you can persist for charts
record = {
"date": as_of,
"base": base,
"pair": "USD/BAM",
"rate": bam_per_usd,
"inverse_pair": "BAM/USD",
"inverse_rate": usd_per_bam,
"timestamp": ts
}
print(record)
If you prefer JavaScript for frontend demos or Node.js jobs, the same pattern applies: fetch latest, validate success, work off base/date/timestamp, and then pull the specific rates you need.
Designing a robust daily BAM time-series pipeline
Most teams want two distinct capabilities: a daily series for historical work and a “fresh” point for the current trading day. Pair the time-series endpoint (for backfills) with latest (for the most recent level) and let your data layer decide which to surface in the UI.
Backfill with the time-series endpoint
The time-series endpoint returns daily rates between a start date and an end date you choose. Parameters and date rules are documented in the Indices-API Documentation. Practical notes for your BAM build:
- Dates are inclusive. Use ISO format YYYY-MM-DD for start_date and end_date.
- Do not set end_date to today. Use yesterday’s date to ensure a finalized daily close is returned.
- Base is USD by default in responses; you’ll typically rely on rates.BAM and/or rates.USDBAM for your charts.
- Weekends and holidays: daily data aligns to the calendar. For currency markets, you may see flat or repeated values across non-business days. Handle these consistently in charts and backtests.
- Data gaps: if a day is missing due to market or provider constraints, keep your renderer robust (forward-fill for visuals, but never for PnL calculations unless explicitly intended).
For code, reuse the parsing pattern from the latest example—time-series responses organize rates by date key. Extract the date bucket, then traverse rates.BAM or rates.USDBAM per day to build your OHLC-equivalent daily line (for FX, you’ll usually have a single daily point unless you’re using intraday endpoints).
Use latest for your live tile and sanity checks
Fetch latest on a schedule during business hours to keep your dashboard tiles fresh and drive alerting. The latest endpoint’s update frequency depends on your plan level; see the docs for plan-specific refresh intervals. When you roll the day at midnight UTC, prefer time-series for the finalized historical print and continue latest for the present day reading.
How quotes will appear in your BAM charts and analytics
Most dashboards opt for one of the following on the y-axis:
- USD/BAM (rates.BAM with base USD): how many BAM per 1 USD.
- BAM/USD (rates.USDBAM with base USD): how many USD per 1 BAM.
Pick the convention your users expect and stick to it across all modules. If you need both, store both; the inverse relationship is deterministic, but caching both can remove any rounding differences in user-facing views.
For percent-change calculations and risk analytics, align to standardized daily closes from the time-series endpoint. When computing intraday percent changes off latest, call latest at a consistent cadence and log the earlier reading you’ll use as the comparison point.
Caching, retries, and production resiliency
Practical notes to keep your BAM pipeline robust:
- Cache latest responses for a short interval aligned with your UI refresh cadence. Don’t spam the endpoint more frequently than your tiles update.
- Respect timestamp and date: always store both. The same date could be reissued if a late correction occurs; use timestamp and your own ingestion time for audits.
- Retries with backoff: network conditions vary. Apply a small exponential backoff and cap retries to avoid thundering herds.
- Idempotence: write your upsert logic so the same date/pair doesn’t duplicate rows on re-ingestion.
- End-of-day finalization: never set end_date to today for time-series pulls. Use yesterday, then roll the window forward each new day.
Choosing endpoints for the job (and where to find the rest)
This workflow centers on:
- Latest: to fetch the current BAM level for dashboards and alerts.
- Time-series: to backfill and maintain a clean daily series for historical analysis and charting.
If you also need day-over-day changes compactly, the fluctuation endpoint can summarize start_rate, end_rate, and change_pct between two dates. For endpoint specifics and optional parameters, consult the Documentation. Always validate the symbol codes you plan to request using the Symbols page before shipping.
Operational checklist before you deploy
- Keys and roles: keep your access_key secure and rotate it on a cadence your org requires. Create a separate key for CI or staging if your process needs it.
- Timezones: treat timestamp as UTC. Persist the UTC seconds and the date string for reproducibility.
- Precision: store rates as decimals or high-precision floats. Avoid binary rounding if you compute long histories or cumulative returns.
- Data lineage: log request URLs (sans key) and the response hash for investigative audits.
- Monitoring: set alerts for non-success responses or when data.rates.BAM and data.rates.USDBAM don’t match within a small numeric tolerance of being inverses.
- UI copy: clearly label the pair (e.g., “USD/BAM”) so users won’t confuse the orientation.
Where BAM fits in your broader macro stack
BAM is pegged to the euro via a currency board arrangement historically linked to the Deutsche Mark, making it relevant in CESEE macro screens, remittance apps, and pricing displays targeting Bosnia and Herzegovina. For context on the currency framework, see the Central Bank of Bosnia and Herzegovina’s resources at cbbh.ba. Pair this with your Indices-API pulls to enrich commentary around your charts if your product exposes notes or annotations.
Getting access and building quickly
You can be testing in minutes with a free trial and then move to PRO ($49.99/mo; 7-day trial) when you’re ready to automate. Create your key here: Register. For a quick overview of the platform and other data domains, visit the homepage at indices-api.com and the model control panel at MCP.
Putting it together: daily job outline
- At T+0 each morning (UTC), call time-series for [yesterday, yesterday] to lock the prior day’s BAM close into your historical table. Do not use today as end_date.
- During market hours, poll latest at a cadence that matches your dashboard tiles or alerts and cache the response briefly.
- For charts, render the time-series history plus a final marker using latest if you want “live” context for the current day.
- For analytics, compute returns off the historical daily points only, or isolate intraday return streams explicitly if needed.
- Monitor for anomalies: inverse check between rates.BAM and rates.USDBAM, success flags, and unexpected nulls.
Common pitfalls and how to avoid them
- Forgetting the base: When base is USD, rates.BAM is USD/BAM in the “how many BAM per 1 USD” sense. If you prefer BAM/USD on your y-axis, use rates.USDBAM.
- End date today: You might get an incomplete or unavailable print. Always use yesterday for finalized daily data.
- Timezone drift: Display times in your user’s locale, but store timestamps in UTC. Use data.date for daily bucketing.
- Weekend handling: Backtests can break if you assume strictly business-day sequences. Use calendar-day indices and forward-fill visually if needed.
Security and environments
- Store access_key in environment variables or your secrets manager. Never hard-code in client apps.
- Apply role separation for staging vs. production keys and rate-limit your own jobs to match your refresh needs.
- Log usage to detect accidental loops or overly aggressive polling.
Useful references and next steps
- Get endpoint specifics, query parameters, and additional features in the Indices-API Documentation.
- Verify the exact symbols you intend to request via the Indices-API Supported Symbols.
- Create or rotate your keys at Register.
- Platform overview and other data domains: indices-api.com.
FAQ
Q: What symbol should I request for Bosnia and Herzegovina Convertible Mark?
A: Use BAM. If you also want the inverse directly, include USDBAM. Always confirm on the Symbols page before shipping.
Q: Are the quotes USD-based? How do I read them?
A: In the sample, base is USD. That means rates.BAM is BAM per 1 USD (USD/BAM), and rates.USDBAM is USD per 1 BAM (BAM/USD). Store both if your app needs both orientations.
Q: Can I query a historical range for BAM?
A: Yes, with the time-series endpoint. Provide start_date and end_date (do not use today for end_date). See parameters and limits in the Documentation.
Q: How often is latest updated?
A: The latest endpoint refresh cadence depends on your plan. Check the docs for your tier’s update frequency and cache accordingly.
Q: Do weekends appear in the time series?
A: Yes, data is organized by calendar date. You may see repeated or flat values on weekends/holidays. Handle this gracefully in charts and backtests.
Ready to plug BAM into your dashboard? Get an API key and start building with the 7-day trial: Register. If you need to explore additional modules or manage models, visit MCP and the main site at indices-api.com.