API Documentation
Use the recurrence.dev API to expand, validate, and manipulate RFC5545 recurrence rules with sub-millisecond response times. Perfect for calendar applications, scheduling systems, and anything that needs reliable recurring events.
Quickstart
Get started in under a minute. Create an account, grab your API key, and make your first request.
Get your API key
Sign up for free and generate your API key from the dashboard.
Make a request
Call the /expand endpoint with your RRULE string.
Get occurrences
Receive an array of ISO 8601 dates back in milliseconds.
Authentication
All API requests require authentication via an API key in the Authorization header.
Authorization: Beareryour_api_key_here
Keep your API key secure
Never expose your API key in client-side code. Use environment variables and server-side requests.
Guides
RRULE Basics
Learn the fundamentals of RFC5545 recurrence rules and how to construct them.
Read more →Working with Timezones
Coming SoonHandle timezone-aware recurrence rules and DST transitions correctly.
Exclusions & Overrides
Coming SoonUse EXDATE, EXRULE, and RDATE to customize occurrence sets.
Error Handling
Understand error codes and implement robust error handling.
Read more →RRULE Basics
RRULE (Recurrence Rule) is part of the RFC5545 iCalendar specification for defining repeating events. An RRULE describes a pattern for recurring dates using a set of properties.
Common Properties
| Property | Description | Example |
|---|---|---|
FREQ |
Frequency of recurrence | DAILY, WEEKLY, MONTHLY, YEARLY |
INTERVAL |
Interval between occurrences | INTERVAL=2 (every 2nd) |
BYDAY |
Days of the week | BYDAY=MO,WE,FR |
BYMONTHDAY |
Days of the month | BYMONTHDAY=1,15 |
BYMONTH |
Months of the year | BYMONTH=1,6,12 |
BYSETPOS |
Position in the set (e.g., 2nd Tuesday) | BYSETPOS=2 or BYSETPOS=-1 (last) |
COUNT |
Total number of occurrences | COUNT=10 |
UNTIL |
End date for recurrence | UNTIL=20261231T235959Z |
Examples
FREQ=DAILY
Every day
FREQ=WEEKLY;BYDAY=MO,WE,FR
Every Monday, Wednesday, and Friday
FREQ=MONTHLY;BYDAY=TU;BYSETPOS=2
Second Tuesday of every month
FREQ=YEARLY;BYMONTH=12;BYMONTHDAY=25
Every December 25th (Christmas)
Try it out
Use the Playground to experiment with different RRULE patterns and see the generated occurrences in real-time.
/v1/expand
Expand a recurrence rule into a list of occurrence dates. This is the core endpoint for generating dates from RRULE strings.
POSThttps://api.recurrence.dev/v1/expand
Request Body (JSON)
| Parameter | Type | Required | Description |
|---|---|---|---|
rrule |
string | Yes | The RRULE string to expand |
dtstart |
string | Yes | Start date in ISO 8601 format |
limit |
integer | No | Max occurrences to return (default: 100, max: 1000) |
until |
string | No | End boundary in ISO 8601 format |
after |
string | No | Cursor for pagination (use moreItemsAfter from previous response) |
Example Request
curl -X POST "https://api.recurrence.dev/v1/expand" \
-H "Authorization: Bearer your_api_key" \
-H "Content-Type: application/json" \
-d '{"rrule": "FREQ=WEEKLY;BYDAY=MO,WE,FR", "dtstart": "2026-01-01T09:00:00Z", "limit": 10}'
Example Response
{
"occurrences": [
"2026-01-02T09:00:00Z",
"2026-01-05T09:00:00Z",
"2026-01-07T09:00:00Z",
"2026-01-09T09:00:00Z",
"2026-01-12T09:00:00Z",
"2026-01-14T09:00:00Z",
"2026-01-16T09:00:00Z",
"2026-01-19T09:00:00Z",
"2026-01-21T09:00:00Z",
"2026-01-23T09:00:00Z"
],
"count": 10,
"moreItemsAfter": "2026-01-23T09:00:00Z"
}
Pagination
When moreItemsAfter is present, pass its value as the after parameter to fetch the next page of results.
/v1/parse
Parse an RRULE string into its structured components. Useful for validation and understanding rule structure without generating occurrences.
POSThttps://api.recurrence.dev/v1/parse
Request Body (JSON)
| Parameter | Type | Required | Description |
|---|---|---|---|
rrule |
string | Yes | The RRULE string to parse |
Example Request
curl -X POST "https://api.recurrence.dev/v1/parse" \
-H "Authorization: Bearer your_api_key" \
-H "Content-Type: application/json" \
-d '{"rrule": "FREQ=DAILY;INTERVAL=2;BYDAY=MO,WE,FR"}'
Example Response
{
"parsed": {
"freq": "DAILY",
"interval": 2,
"byDay": ["MO", "WE", "FR"]
},
"input": "FREQ=DAILY;INTERVAL=2;BYDAY=MO,WE,FR"
}
Error Handling
All API errors return a consistent JSON structure with an error object containing a code and message.
Error Response Format
{
"error": {
"code": "invalid_rrule",
"message": "Invalid RRULE: unknown frequency 'DAILYY'"
}
}
Error Codes
| Code | Status | Description |
|---|---|---|
missing_param |
400 | A required parameter is missing |
invalid_rrule |
400 | The RRULE string is malformed or invalid |
invalid_datetime |
400 | The datetime value is not valid ISO 8601 format |
invalid_batch_size |
400 | The batch_size parameter is invalid (streaming endpoint) |
rrule_limit_exceeded |
400 | RRULE component values exceed allowed limits |
missing_token |
401 | Authorization header is missing |
invalid_token |
401 | API token is invalid or expired |
not_found |
404 | The requested resource was not found |
config_not_supported |
422 | RRULE configuration exceeds plan limits |
rate_limited |
429 | Too many requests, check Retry-After header |
internal_error |
500 | An unexpected server error occurred |
Rate Limits
Rate limits are enforced per API key. Limits reset at the start of each calendar month.
| Plan | Monthly Limit | Burst Rate |
|---|---|---|
| Developer | 1,000 requests | 10/sec |
| Enterprise | Custom | Custom |
Rate limit headers
Check X-RateLimit-Remaining and X-RateLimit-Reset headers to track your usage.