# Building a Historical Time Series

If you need a time series of swap rates over days, weeks, or months, the BlueGamma API offers two approaches depending on the granularity you need.

***

## Option 1: Daily snapshots with `/historical_swap_rates`

The `/historical_swap_rates` endpoint returns daily swap rates for a given index and tenor across a date range in a single call. This is the simplest way to build a time series.

```python
import requests

url = "https://api.bluegamma.io/v1/historical_swap_rates"
headers = {"x-api-key": "your_api_key_here"}

params = {
    "index": "SOFR",
    "tenor": "5Y",
    "start_date": "2026-03-23",
    "end_date": "2026-03-27"
}

response = requests.get(url, headers=headers, params=params)
data = response.json()

for point in data["swap_rates"]:
    print(f"{point['date']}: {point['rate']:.4f}%")
```

```bash
curl -X GET "https://api.bluegamma.io/v1/historical_swap_rates?index=SOFR&tenor=5Y&start_date=2026-03-23&end_date=2026-03-27" \
  -H "x-api-key: your_api_key_here"
```

**Response:**

```json
{
  "index_name": "SOFR",
  "currency": "USD",
  "fixed_leg_day_count": "Actual360",
  "floating_leg_day_count": "Actual360",
  "fixed_leg_frequency": "12M",
  "floating_leg_frequency": "12M",
  "swap_rates": [
    { "rate": 3.5944, "date": "2026-03-23", "tenor": "5Y" },
    { "rate": 3.6530, "date": "2026-03-23", "tenor": "5Y" },
    { "rate": 3.6027, "date": "2026-03-24", "tenor": "5Y" },
    { "rate": 3.6614, "date": "2026-03-24", "tenor": "5Y" },
    { "rate": 3.6184, "date": "2026-03-25", "tenor": "5Y" },
    { "rate": 3.6720, "date": "2026-03-25", "tenor": "5Y" },
    { "rate": 3.6854, "date": "2026-03-26", "tenor": "5Y" },
    { "rate": 3.7373, "date": "2026-03-26", "tenor": "5Y" }
  ]
}
```

### Parameters

| Parameter    | Required | Description                                                        |
| ------------ | -------- | ------------------------------------------------------------------ |
| `index`      | Yes      | Interest rate index (e.g., `SOFR`, `SONIA`, `6M EURIBOR`)          |
| `tenor`      | Yes      | Swap tenor (e.g., `1Y`, `5Y`, `10Y`)                               |
| `start_date` | Yes      | Start of the date range, inclusive (ISO 8601 format: `YYYY-MM-DD`) |
| `end_date`   | Yes      | End of the date range, inclusive (ISO 8601 format: `YYYY-MM-DD`)   |

### Response fields

| Field                    | Description                                                    |
| ------------------------ | -------------------------------------------------------------- |
| `index_name`             | The index requested                                            |
| `currency`               | Currency of the swap                                           |
| `fixed_leg_day_count`    | Day count convention used for the fixed leg                    |
| `floating_leg_day_count` | Day count convention used for the floating leg                 |
| `fixed_leg_frequency`    | Payment frequency of the fixed leg                             |
| `floating_leg_frequency` | Payment frequency of the floating leg                          |
| `swap_rates`             | Array of rate snapshots, each with `rate`, `date`, and `tenor` |

{% hint style="info" %}
You may see multiple rate entries per date. These represent snapshots captured at different times during the day (e.g., European and US market closes). Use the last entry for a given date if you want end-of-day rates.
{% endhint %}

***

## Option 2: Intraday time series with `/swap_rate` + `valuation_time`

If you need rates at specific times during the day, use the `/swap_rate` endpoint with the `valuation_time` parameter. Each call returns a single rate, so you loop through your desired timestamps.

```python
import requests
from datetime import datetime, timedelta

url = "https://api.bluegamma.io/v1/swap_rate"
headers = {"x-api-key": "your_api_key_here"}

# Generate hourly timestamps for a single day
base_date = datetime(2026, 3, 25, 8, 0, 0)  # Start at 8am UTC
timestamps = [base_date + timedelta(hours=i) for i in range(10)]  # 8am to 5pm

rates = []
for ts in timestamps:
    params = {
        "index": "SOFR",
        "start_date": "0D",
        "maturity_date": "5Y",
        "fixed_leg_frequency": "1Y",
        "floating_leg_frequency": "1Y",
        "fixed_leg_day_count": "Actual360",
        "valuation_time": ts.isoformat() + "Z"
    }
    response = requests.get(url, headers=headers, params=params)
    if response.status_code == 200:
        data = response.json()
        rates.append({
            "time": ts,
            "rate": data["swap_rate"]
        })

for r in rates:
    print(f"{r['time'].strftime('%H:%M')}: {r['rate']:.4f}%")
```

```bash
curl -X GET "https://api.bluegamma.io/v1/swap_rate?index=SOFR&start_date=0D&maturity_date=5Y&fixed_leg_frequency=1Y&floating_leg_frequency=1Y&fixed_leg_day_count=Actual360&valuation_time=2026-03-25T10%3A00%3A00Z" \
  -H "x-api-key: your_api_key_here"
```

**Response:**

```json
{
  "index": "SOFR",
  "start_date": "2026-04-01",
  "maturity_date": "2031-04-01",
  "fixed_leg_frequency": "1Y",
  "fixed_leg_day_count": "Actual360",
  "floating_leg_frequency": "1Y",
  "floating_leg_day_count": "Actual360",
  "valuation_time": "2026-03-25T10:00:00",
  "swap_rate": 3.6184,
  "timestamp": "2026-03-25T09:59:23"
}
```

***

## Which approach should I use?

|                 | `/historical_swap_rates`                        | `/swap_rate` + `valuation_time`                       |
| --------------- | ----------------------------------------------- | ----------------------------------------------------- |
| **Granularity** | Daily                                           | Any (hourly, per-minute, etc.)                        |
| **API calls**   | 1 call per date range                           | 1 call per timestamp                                  |
| **Best for**    | End-of-day charts, trend analysis, reporting    | Intraday monitoring, precise point-in-time valuations |
| **Conventions** | Uses market-standard conventions for each index | You specify leg frequencies and day counts            |
| **Date range**  | Any historical range                            | Any historical timestamp                              |

***

## Practical example: 1-year daily chart

```python
import requests
import matplotlib.pyplot as plt
from datetime import datetime

url = "https://api.bluegamma.io/v1/historical_swap_rates"
headers = {"x-api-key": "your_api_key_here"}

params = {
    "index": "SOFR",
    "tenor": "5Y",
    "start_date": "2025-04-01",
    "end_date": "2026-04-01"
}

response = requests.get(url, headers=headers, params=params)
data = response.json()

# Take the last rate per date (end-of-day)
daily = {}
for point in data["swap_rates"]:
    daily[point["date"]] = point["rate"]

dates = [datetime.strptime(d, "%Y-%m-%d") for d in sorted(daily.keys())]
rates = [daily[d.strftime("%Y-%m-%d")] for d in dates]

plt.figure(figsize=(10, 5))
plt.plot(dates, rates, linewidth=1)
plt.xlabel("Date")
plt.ylabel("Swap Rate (%)")
plt.title("5Y SOFR Swap Rate - 1 Year History")
plt.tight_layout()
plt.show()
```

<figure><img src="https://3184259219-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FmmQPefoflG1RwUnUKKBR%2Fuploads%2Fgit-blob-da8b64920a04b1a111cb457573b6a7f7ea6b76d3%2Fhistorical-time-series-sofr-5y.png?alt=media" alt="5Y SOFR swap rate over 1 year, showing daily end-of-day rates from April 2025 to April 2026"><figcaption><p>5Y SOFR swap rate: 1-year daily history built with /historical_swap_rates</p></figcaption></figure>

***

## Related Endpoints

| If you need...                 | Use                                                                                                           |
| ------------------------------ | ------------------------------------------------------------------------------------------------------------- |
| A single live swap rate        | [`/swap_rate`](https://bluegamma.io/documentation/integrations/api/how-to-guides/fetching-a-swap-rate)        |
| A full swap curve (all tenors) | [`/get_swap_curve`](https://bluegamma.io/documentation/integrations/api/how-to-guides/fetching-a-swap-curve)  |
| Forward rate curves            | [`/forward_curve`](https://bluegamma.io/documentation/integrations/api/how-to-guides/getting-a-forward-curve) |

***

**Need an API key?** [Book a demo](https://app.lemcal.com/@alivohra/website-demo?back=1) | <support@bluegamma.io>
