# Fetching Forward Curves

The `/forward_curve` endpoint returns a series of forward rates over time. Use this for dashboards, pricing models, cash flow projections, and interest rate forecasts.

***

## Basic Example

```python
import requests

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

params = {
    "index": "SOFR",
    "start_date": "0D",
    "end_date": "10Y",
    "tenor": "3M",
    "frequency": "3M"
}

response = requests.get(url, headers=headers, params=params)
data = response.json()
curve = data["curve"]
```

```bash
curl -X GET "https://api.bluegamma.io/v1/forward_curve?index=SOFR&start_date=0D&end_date=10Y&tenor=3M&frequency=3M" \
  -H "x-api-key: your_api_key_here"
```

**Response:**

```json
{
  "start_date": "2025-12-17",
  "end_date": "2035-12-17",
  "index": "SOFR",
  "valuation_time": "2025-12-17T10:22:04.246666",
  "tenor": "3M",
  "frequency": "3M",
  "curve": [
    {"start_date": "2025-12-17", "end_date": "2026-03-17", "forward_rate": 4.31},
    {"start_date": "2026-03-17", "end_date": "2026-06-17", "forward_rate": 3.89},
    {"start_date": "2026-06-17", "end_date": "2026-09-17", "forward_rate": 3.65},
    {"start_date": "2026-09-17", "end_date": "2026-12-17", "forward_rate": 3.52}
  ],
  "timestamp": "2025-12-17T10:21:29"
}
```

| Field                     | Description                        |
| ------------------------- | ---------------------------------- |
| `curve`                   | Array of forward rate points       |
| `forward_rate`            | The forward rate as a percentage   |
| `start_date` / `end_date` | The period the forward rate covers |
| `valuation_time`          | When the curve was calculated      |
| `timestamp`               | When the market data was captured  |

***

## Parameters

| Parameter        | Required | Description                                                                |
| ---------------- | -------- | -------------------------------------------------------------------------- |
| `index`          | Yes      | Interest rate index (e.g., `SOFR`, `SONIA`, `6M EURIBOR`)                  |
| `start_date`     | Yes      | Start of the curve, relative (`0D`, `1M`, `1Y`) or absolute (`2025-12-17`) |
| `end_date`       | Yes      | End of the curve                                                           |
| `tenor`          | Yes      | Length of each forward period (e.g., `1M`, `3M`, `6M`)                     |
| `frequency`      | Yes      | Spacing between curve points (e.g., `3M`, `1Y`)                            |
| `valuation_time` | No       | Historical timestamp (ISO 8601) for reproducibility                        |

***

## When to Use Forward Curves

| Use Case                 | Example                                          |
| ------------------------ | ------------------------------------------------ |
| **Cash flow projection** | Project floating rate payments on a loan or swap |
| **Dashboard / UI**       | Display the market's rate expectations           |
| **Scenario analysis**    | Compare current curve to historical snapshots    |
| **Model calibration**    | Feed forward rates into a pricing model          |

<figure><img src="/files/f5NwBZIGGRTBIKy9PHdx" alt="SOFR forward curve comparison: December 2025 vs December 2024"><figcaption><p>SOFR forward curve: now vs 1 year ago</p></figcaption></figure>

The chart shows how rate expectations have shifted over the past year:

* **Dec 2024** (grey): Relatively flat curve around 3.75–3.95%
* **Dec 2025** (blue): Sharp dip to \~3.1% at 1Y (rate cuts priced in), then steepening to 4.4% at 10Y

Use `valuation_time` to compare curves at different points in time.

***

## Curve Access Patterns: Fetch vs Store

When integrating forward curves, you can either **fetch on-demand** or **store snapshots locally**. The right choice depends on your workflow.

### Fetch on Demand

Best for flexibility and fresh data:

* Live dashboards and UIs
* Ad-hoc pricing with user-defined date ranges
* One-off analysis

```python
# Just call the API when you need it
response = requests.get(url, headers=headers, params=params)
curve = response.json()["curve"]
```

### Store Snapshots

Best for speed, reproducibility, and audit trails:

* Monthly/quarterly valuations
* Batch processing that queries the same curves repeatedly
* Any workflow where you need to prove what curve you used

```python
# Fetch and store with full context
response = requests.get(url, headers=headers, params=params)
data = response.json()

db.insert("curve_snapshots", {
    "valuation_time": data["valuation_time"],
    "timestamp": data["timestamp"],
    "index": data["index"],
    "curve": data["curve"]
})
```

### Quick Comparison

|                     | Fetch on Demand   | Store Snapshots     |
| ------------------- | ----------------- | ------------------- |
| **Setup**           | Simple            | Requires storage    |
| **Speed**           | API latency       | Instant             |
| **Reproducibility** | Requires logging  | Built-in            |
| **Best for**        | Real-time, ad-hoc | Periodic, auditable |

***

## Reproducibility with `valuation_time`

For reproducible valuations, use `valuation_time` to lock in the market state at a specific point in time:

```python
params = {
    "index": "SOFR",
    "start_date": "0D",
    "end_date": "10Y",
    "tenor": "3M",
    "frequency": "3M",
    "valuation_time": "2024-06-30T16:00:00Z"  # ISO 8601 format
}

response = requests.get(url, headers=headers, params=params)
```

```bash
curl -X GET "https://api.bluegamma.io/v1/forward_curve?index=SOFR&start_date=0D&end_date=10Y&tenor=3M&frequency=3M&valuation_time=2024-06-30T16%3A00%3A00Z" \
  -H "x-api-key: your_api_key_here"
```

Without `valuation_time`, you get the latest data. With it, you get the curve exactly as it was at that timestamp—essential for reproducing valuations months later.

***

## Hybrid Approach

Many workflows combine both patterns—store snapshots for fixed valuation dates, fetch on demand for everything else:

```python
def get_curve(index: str, valuation_time: str = None):
    # Check local cache first
    if valuation_time:
        stored = db.query(
            "SELECT curve FROM snapshots WHERE index = ? AND valuation_time = ?",
            [index, valuation_time]
        )
        if stored:
            return stored["curve"]
    
    # Fetch from API
    params = {
        "index": index,
        "start_date": "0D",
        "end_date": "10Y",
        "tenor": "3M",
        "frequency": "3M"
    }
    if valuation_time:
        params["valuation_time"] = valuation_time
    
    response = requests.get(url, headers=headers, params=params)
    return response.json()["curve"]
```

***

## Storage Schema

If you're storing curves, here's a suggested schema:

| Column           | Type      | Description                                     |
| ---------------- | --------- | ----------------------------------------------- |
| `valuation_time` | TIMESTAMP | When the curve was calculated                   |
| `timestamp`      | TIMESTAMP | Market data timestamp                           |
| `index`          | VARCHAR   | e.g., `"SOFR"`, `"6M EURIBOR"`                  |
| `curve`          | JSON      | Array of `{start_date, end_date, forward_rate}` |
| `created_at`     | TIMESTAMP | When you captured it                            |

***

## Supported Indices

| Index        | Currency | Description                          |
| ------------ | -------- | ------------------------------------ |
| `SOFR`       | USD      | Secured Overnight Financing Rate     |
| `SONIA`      | GBP      | Sterling Overnight Index Average     |
| `ESTR`       | EUR      | Euro Short-Term Rate                 |
| `6M EURIBOR` | EUR      | 6-Month Euro Interbank Offered Rate  |
| `CORRA`      | CAD      | Canadian Overnight Repo Rate Average |

For the full list, see [Available Indices](/documentation/integrations/available-indices.md).

***

## Related Endpoints

| If you need...             | Use                                                                                             |
| -------------------------- | ----------------------------------------------------------------------------------------------- |
| A single forward rate      | [`/forward_rate`](/documentation/integrations/api/how-to-guides/getting-forward-rates.md)       |
| Zero rates for discounting | [`/zero_rate`](/documentation/integrations/api/how-to-guides/fetching-zero-rates.md)            |
| Discount factors           | [`/discount_factor`](/documentation/integrations/api/how-to-guides/getting-discount-factors.md) |
| The underlying swap curve  | [`/swap_curve`](/documentation/integrations/api/how-to-guides/fetching-a-swap-curve.md)         |

***

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


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://bluegamma.io/documentation/integrations/api/how-to-guides/getting-a-forward-curve.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
