# Recurrence Rule API
> Expand and describe RFC 5545 recurrence rules — the RRULE that powers calendar repeats. The expand endpoint takes an RRULE and a start date-time and returns the next occurrence dates, correctly handling FREQ (daily, weekly, monthly, yearly and the finer hourly/minutely/secondly), INTERVAL (every 2 weeks…), COUNT and UNTIL, BYDAY including ordinals like 2MO or -1FR (so "the last Friday of the month" or "the third Sunday of June"), BYMONTHDAY including negatives (-1 for the last day of the month), BYMONTH and WKST. The describe endpoint turns a rule into a plain-English sentence such as "every week on Monday, Wednesday and Friday, 10 times". Everything is computed locally in UTC and deterministically, so it is instant, private and identical on every machine. Ideal for scheduling and booking systems, calendar and reminder apps, billing and subscription cycles, job and report scheduling, and showing customers when something next happens. Pure local computation — no key, no third-party service, instant. Live, nothing stored. 3 endpoints. This expands the recurrence rule; to build a downloadable .ics calendar event use an iCalendar API, and for plain date arithmetic use a date-time API.

## Authentication
All requests require your oanor API key in the `x-oanor-key` header. Get one at https://www.oanor.com/developer/keys.

```bash
curl -H "x-oanor-key: oanor_live_…" "https://api.oanor.com/rrule-api/..."
```

## Pricing
- **Free** (Free) — 3,835 calls/Mo, 2 req/s
- **Starter** ($5/Mo) — 13,350 calls/Mo, 8 req/s
- **Pro** ($25/Mo) — 184,500 calls/Mo, 20 req/s
- **Mega** ($63/Mo) — 965,000 calls/Mo, 50 req/s

## Endpoints

### Recurrence

#### `GET /v1/describe` — Describe a recurrence rule

**Parameters:**
- `rrule` (query, required, string) — The RRULE Example: `FREQ=MONTHLY;BYDAY=-1FR`

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/rrule-api/v1/describe?rrule=FREQ%3DMONTHLY%3BBYDAY%3D-1FR"
```

**Response:**
```json
{
    "data": {
        "text": "every month on last Friday",
        "rrule": "FREQ=MONTHLY;BYDAY=-1FR"
    },
    "meta": {
        "timestamp": "2026-06-03T09:24:58.998Z",
        "request_id": "6adebe59-86b8-4002-a204-8c1998f5ec95"
    },
    "status": "ok",
    "message": "Describe a recurrence rule",
    "success": true
}
```

#### `GET /v1/expand` — Expand a recurrence rule

**Parameters:**
- `rrule` (query, required, string) — The RRULE Example: `FREQ=WEEKLY;BYDAY=MO,WE,FR;COUNT=10`
- `start` (query, required, string) — Start date-time (ISO 8601 UTC) Example: `2026-01-05T09:00:00Z`
- `count` (query, optional, string) — Max occurrences (default 10, max 1000) Example: `10`

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/rrule-api/v1/expand?rrule=FREQ%3DWEEKLY%3BBYDAY%3DMO%2CWE%2CFR%3BCOUNT%3D10&start=2026-01-05T09%3A00%3A00Z&count=10"
```

**Response:**
```json
{
    "data": {
        "count": 10,
        "rrule": "FREQ=WEEKLY;BYDAY=MO,WE,FR;COUNT=10",
        "start": "2026-01-05T09:00:00.000Z",
        "finite": true,
        "occurrences": [
            "2026-01-05T09:00:00.000Z",
            "2026-01-07T09:00:00.000Z",
            "2026-01-09T09:00:00.000Z",
            "2026-01-12T09:00:00.000Z",
            "2026-01-14T09:00:00.000Z",
            "2026-01-16T09:00:00.000Z",
            "2026-01-19T09:00:00.000Z",
            "2026-01-21T09:00:00.000Z",
            "2026-01-23T09:00:00.000Z",
            "2026-01-26T09:00:00.000Z"
        ]
    },
    "meta": {
        "timestamp": "2026-06-03T09:24:59.094Z",
        "request_id": "bd815b7e-2beb-4bd9-a594-5f163d06aec9"
    },
    "status": "ok",
    "message": "Expand a recurrence rule",
    "success": true
}
```

### Meta

#### `GET /v1/meta` — Spec

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/rrule-api/v1/meta"
```

**Response:**
```json
{
    "data": {
        "name": "Recurrence Rule API",
        "notes": "Dates are handled in UTC. An infinite rule (no COUNT or UNTIL) is capped by the count parameter. This expands the recurrence rule; to build a full .ics calendar event use an iCalendar API and for plain date arithmetic use a date-time API. Nothing is stored.",
        "version": "v1",
        "endpoints": [
            {
                "path": "/v1/expand",
                "params": {
                    "count": "max occurrences to return (default 10, max 1000)",
                    "rrule": "the RRULE, e.g. FREQ=WEEKLY;BYDAY=MO,WE,FR;COUNT=10 (required)",
                    "start": "the start date-time, ISO 8601 UTC (required)"
                },
                "returns": "the list of occurrence date-times"
            },
            {
                "path": "/v1/describe",
                "params": {
                    "rrule": "the RRULE (required)"
                },
                "returns": "a plain-English description of the rule"
            },
            {
                "path": "/v1/meta",
                "params": [],
                "returns": "this document"
            }
        ],
        "description": "Expand and describe RFC 5545 recurrence rules (the RRULE behind calendar repeats). The expand endpoint takes an RRULE and a start date-time and returns the next occurrence dates — handling FREQ (daily, weekly, monthly, yearly and finer), INTERVAL, COUNT, UNTIL, BYDAY (including 
…(truncated, see openapi.json for full schema)
```


---
Marketplace page: https://www.oanor.com/api/rrule-api
OpenAPI spec: https://www.oanor.com/api/rrule-api/openapi.json
