> From TickerLayer docs, Futures CFDs: https://tickerlayer.com/docs/products/futures#futures-roll-calendar
> REST base URL https://api.tickerlayer.com, API key in the `x-api-key` header. WebSocket wss://stream.tickerlayer.com?apiKey=YOUR_API_KEY. Full API reference: https://tickerlayer.com/llms-full.txt

## Roll calendar

**Endpoint:** `GET /futures/roll-calendar/:base`

Every chain rotation and roll window of a product, from the current one on. Open to any valid key.

### Path parameters

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `base` | string | Yes | Product base, for example WTIUSD, XAUUSD or UST5Y. GET /futures/products lists them. |

### Query parameters

| Parameter | Type | Description |
| --- | --- | --- |
| `months` | integer | How far ahead to list, from 1 to 36 months. Default 12. |

### Request

```bash
curl -sS "https://api.tickerlayer.com/futures/roll-calendar/WTIUSD?months=2" \
  -H "x-api-key: <YOUR_API_KEY>"
```

```python
import requests

res = requests.get(
    "https://api.tickerlayer.com/futures/roll-calendar/WTIUSD?months=2",
    headers={"x-api-key": "<YOUR_API_KEY>"},
)
print(res.json())
```

```javascript
const res = await fetch("https://api.tickerlayer.com/futures/roll-calendar/WTIUSD?months=2", {
  headers: { "x-api-key": "<YOUR_API_KEY>" },
});
const data = await res.json();
console.log(data);
```

```go
req, _ := http.NewRequest("GET", "https://api.tickerlayer.com/futures/roll-calendar/WTIUSD?months=2", nil)
req.Header.Set("x-api-key", "<YOUR_API_KEY>")
```

### Response

```json
{
  "base": "WTIUSD",
  "name": "WTI crude oil",
  "rolls": [
    {
      "front": "WTIUSD.DEC26",
      "next": "WTIUSD.JAN27",
      "roll_window_start": "2026-11-05T23:00:00.000Z",
      "roll_window_end": "2026-11-12T22:00:00.000Z",
      "roll_window_days": ["2026-11-06", "2026-11-09", "2026-11-10",
                           "2026-11-11", "2026-11-12"],
      "cycle_start": "2026-10-19T22:00:00.000Z",
      "first_notice_date": "2026-11-30",
      "last_trade_date": "2026-11-20",
      "rotation_at": "2026-11-19T23:00:00.000Z"
    },
    {
      "front": "WTIUSD.JAN27",
      "next": "WTIUSD.FEB27",
      "roll_window_start": "2026-12-06T23:00:00.000Z",
      "roll_window_end": "2026-12-11T22:00:00.000Z",
      "roll_window_days": ["2026-12-07", "2026-12-08", "2026-12-09",
                           "2026-12-10", "2026-12-11"],
      "cycle_start": "2026-11-19T23:00:00.000Z",
      "first_notice_date": "2026-12-31",
      "last_trade_date": "2026-12-21",
      "rotation_at": "2026-12-20T23:00:00.000Z"
    }
  ]
}
```

### Notes

`roll_window_days` are the five trade dates the `.R5` and `.R5C` weights move on. `cycle_start` is when the `.CYCLE` weight of this front starts counting, and `rotation_at` when `C1` moves to `next`. A `months` value outside 1 to 36 answers `400 months must be a whole number from 1 to 36`.
