ICS Parser Online
Parse .ics calendars into JSON events, expand RRULE recurrences in a date range, convert time zones, merge calendars and find free slots.
Result
Press “Run” to see the result.
Send iCalendar text as ics (or as a raw text/calendar body), a file, a url / urls (public feeds, webcal:// accepted, up to 5 per request) or calendars (an array of texts or {url} objects) to merge several calendars. Each event comes back with summary, description, location, URL, status, transparency, categories, organizer and attendees, alarms, start / end in the target timezone (ISO 8601 with offset; YYYY-MM-DD for all-day events, end exclusive), start_utc / end_utc, duration and the original time zone. Times with a TZID use the IANA zone, or the calendar’s own VTIMEZONE when the name is not an IANA one (Outlook), a few Windows names are mapped, and floating times are read in the target zone.
With from / to (dates are inclusive, read in the target zone) recurring series are expanded: RRULE with FREQ (minutely to yearly), INTERVAL, COUNT, UNTIL, BYDAY with ordinals (1FR, -1SU), BYMONTHDAY, BYMONTH, BYYEARDAY, BYHOUR / BYMINUTE / BYSECOND, BYSETPOS and WKST, plus RDATE, EXDATE and moved or cancelled instances (RECURRENCE-ID). Recurrences keep their wall-clock time across daylight-saving changes. Without a range, events are returned as stored with their rrule (expand=true lists the first occurrences); limit caps the output (default 1000, max 5000).
free_slots=true merges the busy time of all calendars (cancelled and transparent events ignored, all-day events only with all_day_busy=true) and returns the free intervals inside working hours (work_start, work_end, work_days as ISO weekdays, min_minutes) for up to 62 days (default: 7 days from today). Nothing is stored.
Use this in your code
curl -X POST "https://apibox.io.vn/v1/ics-parse" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"ics":"BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//APIBox//demo//VI\r\nX-WR-CALNAME:Nhóm dự án\r\nX-WR-TIMEZONE:Asia/Ho_Chi_Minh\r\nBEGIN:VEVENT\r\nUID:standup@example.vn\r\nDTSTART;TZID=Asia/Ho_Chi_Minh:20261116T090000\r\nDTEND;TZID=Asia/Ho_Chi_Minh:20261116T093000\r\nRRULE:FREQ=WEEKLY;BYDAY=MO,WE,FR;COUNT=12\r\nSUMMARY:Họp đầu ngày\r\nLOCATION:Phòng 3\r\nEND:VEVENT\r\nBEGIN:VEVENT\r\nUID:demo@example.vn\r\nDTSTART:20261117T070000Z\r\nDTEND:20261117T083000Z\r\nSUMMARY:Demo khách hàng\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n","from":"2026-11-16","to":"2026-11-17","free_slots":true,"work_start":"08:30","work_end":"17:30"}'const res = await fetch('https://apibox.io.vn/v1/ics-parse', {
method: 'POST',
headers: {
Authorization: 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"ics": "BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//APIBox//demo//VI\r\nX-WR-CALNAME:Nhóm dự án\r\nX-WR-TIMEZONE:Asia/Ho_Chi_Minh\r\nBEGIN:VEVENT\r\nUID:standup@example.vn\r\nDTSTART;TZID=Asia/Ho_Chi_Minh:20261116T090000\r\nDTEND;TZID=Asia/Ho_Chi_Minh:20261116T093000\r\nRRULE:FREQ=WEEKLY;BYDAY=MO,WE,FR;COUNT=12\r\nSUMMARY:Họp đầu ngày\r\nLOCATION:Phòng 3\r\nEND:VEVENT\r\nBEGIN:VEVENT\r\nUID:demo@example.vn\r\nDTSTART:20261117T070000Z\r\nDTEND:20261117T083000Z\r\nSUMMARY:Demo khách hàng\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n",
"from": "2026-11-16",
"to": "2026-11-17",
"free_slots": true,
"work_start": "08:30",
"work_end": "17:30"
}),
});
const data = await res.json();
console.log(data);import requests
res = requests.post(
"https://apibox.io.vn/v1/ics-parse",
headers={"Authorization": "Bearer YOUR_API_KEY"},
json={"ics": "BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//APIBox//demo//VI\r\nX-WR-CALNAME:Nhóm dự án\r\nX-WR-TIMEZONE:Asia/Ho_Chi_Minh\r\nBEGIN:VEVENT\r\nUID:standup@example.vn\r\nDTSTART;TZID=Asia/Ho_Chi_Minh:20261116T090000\r\nDTEND;TZID=Asia/Ho_Chi_Minh:20261116T093000\r\nRRULE:FREQ=WEEKLY;BYDAY=MO,WE,FR;COUNT=12\r\nSUMMARY:Họp đầu ngày\r\nLOCATION:Phòng 3\r\nEND:VEVENT\r\nBEGIN:VEVENT\r\nUID:demo@example.vn\r\nDTSTART:20261117T070000Z\r\nDTEND:20261117T083000Z\r\nSUMMARY:Demo khách hàng\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n", "from": "2026-11-16", "to": "2026-11-17", "free_slots": True, "work_start": "08:30", "work_end": "17:30"},
timeout=30,
)
print(res.json())<?php
$ch = curl_init('https://apibox.io.vn/v1/ics-parse');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => ['Authorization: Bearer YOUR_API_KEY', 'Content-Type: application/json'],
CURLOPT_POSTFIELDS => '{"ics":"BEGIN:VCALENDAR\\r\\nVERSION:2.0\\r\\nPRODID:-//APIBox//demo//VI\\r\\nX-WR-CALNAME:Nhóm dự án\\r\\nX-WR-TIMEZONE:Asia/Ho_Chi_Minh\\r\\nBEGIN:VEVENT\\r\\nUID:standup@example.vn\\r\\nDTSTART;TZID=Asia/Ho_Chi_Minh:20261116T090000\\r\\nDTEND;TZID=Asia/Ho_Chi_Minh:20261116T093000\\r\\nRRULE:FREQ=WEEKLY;BYDAY=MO,WE,FR;COUNT=12\\r\\nSUMMARY:Họp đầu ngày\\r\\nLOCATION:Phòng 3\\r\\nEND:VEVENT\\r\\nBEGIN:VEVENT\\r\\nUID:demo@example.vn\\r\\nDTSTART:20261117T070000Z\\r\\nDTEND:20261117T083000Z\\r\\nSUMMARY:Demo khách hàng\\r\\nEND:VEVENT\\r\\nEND:VCALENDAR\\r\\n","from":"2026-11-16","to":"2026-11-17","free_slots":true,"work_start":"08:30","work_end":"17:30"}',
]);
$response = curl_exec($ch);
print_r(json_decode($response, true));API documentation → Get a free API key
FAQ
Why do some recurring events look one hour off?
They do not: occurrences keep their local time in the event’s time zone, so the UTC time moves when daylight saving starts or ends, as calendar apps do.
Which RRULE parts are not supported?
BYWEEKNO and FREQ=SECONDLY; such series return only their first instance with a warning.
Is my calendar stored?
No. Calendars are parsed in memory for the request and discarded; URL feeds are fetched each time.