CorrectICS

How to Validate & Fix ICS Files Programmatically (Node, Python, Bash)

A practical guide for developers integrating calendar exports, ICS feeds, or user-uploaded .ics files

ICS (iCalendar) files are the standard format for calendar events — but real-world ICS files are often malformed, missing fields, or rejected by Google Calendar, Outlook, or Apple Calendar.

If your app:

  • imports user-provided ICS files
  • exports ICS files
  • syncs events between vendors
  • ingests ICS feeds
  • uses ICS in CI/testing

…you’ll quickly run into subtle failures around:

  • invalid DTSTART / DTEND
  • TZID / time zone mismatches
  • missing UID or PRODID
  • malformed RRULE
  • bad line endings or folding
  • missing BEGIN:VCALENDAR / END:VCALENDAR

This guide shows you how to automatically validate, lint, and autofix ICS files programmatically, using:

  • Node.js
  • Python
  • Bash / cURL

All examples use the CorrectICS API, which provides:

  • strict validation
  • human-readable error messages
  • auto-correction of common issues
  • clean output compatible with Google, Outlook, and Apple Calendar

1. Why programmatic ICS validation is necessary

Manual checking of ICS files is not scalable:

  • ICS parsers don’t validate strictly
  • Google/Outlook silently reject some files
  • Vendors output non-standard time zones
  • RRULEs differ across clients
  • Files can be long, folded, or deeply nested

If you’re ingesting ICS at scale (SaaS, marketplace integrations, booking systems), you need:

  • consistent validation
  • clear errors for debugging
  • automatic fixes
  • CI or ingestion pipeline support

2. API Overview: Validate vs Autofix

Validate endpoint

Checks ICS for:

  • spec violations
  • missing fields
  • invalid time zones
  • malformed RRULEs
  • structural issues

Returns:

  • valid: true/false
  • list of errors, warnings, hints

Autofix endpoint

  • repairs time zones
  • inserts missing UID/PRODID
  • fixes missing boundaries
  • corrects RRULE errors
  • normalizes line endings & folding
  • returns a fixed .ics file

Used for ingestion pipelines or automated exports.


3. Quickstart (Bash / cURL)

Validate an ICS file

curl -X POST https://api.correctics.com/v1/validate \
  -H "Content-Type: text/calendar" \
  --data-binary @event.ics

Autofix an ICS file

curl -X POST https://api.correctics.com/v1/autofix \
  -H "Content-Type: text/calendar" \
  --data-binary @event.ics \
  -o fixed.ics

Response example (validation)

{
  "valid": false,
  "errors": [
    {
      "code": "MISSING_DTSTART",
      "message": "VEVENT is missing a DTSTART property",
      "line": 12
    },
    {
      "code": "INVALID_TZID",
      "message": "TZID 'EST' is not a valid IANA timezone",
      "line": 18
    }
  ],
  "warnings": []
}

4. Node.js Example — Validate an ICS File

No client library required — just use fetch (Node 18+):

npm init -y

validate.js

import { readFileSync } from 'fs';

async function validateICS(path) {
  const data = readFileSync(path);
  const res = await fetch('https://api.correctics.com/v1/validate', {
    method: 'POST',
    headers: { 'Content-Type': 'text/calendar' },
    body: data,
  });
  const result = await res.json();
  console.log(result);
}

validateICS('broken.ics');

Run:

node validate.js

5. Node.js Example — Autofix an ICS File

autofix.js

import { readFileSync, writeFileSync } from 'fs';

async function autofixICS(inputPath, outputPath) {
  const data = readFileSync(inputPath);
  const res = await fetch('https://api.correctics.com/v1/autofix', {
    method: 'POST',
    headers: { 'Content-Type': 'text/calendar' },
    body: data,
  });
  const fixed = await res.text();
  writeFileSync(outputPath, fixed);
  console.log(`ICS file fixed and saved to ${outputPath}`);
}

autofixICS('broken.ics', 'fixed.ics');

6. Python Example — Validate an ICS File

Install:

pip install requests

validate.py

import requests

with open('broken.ics', 'rb') as f:
    data = f.read()

res = requests.post(
    'https://api.correctics.com/v1/validate',
    headers={'Content-Type': 'text/calendar'},
    data=data,
)

print(res.json())

7. Python Example — Autofix an ICS File

autofix.py

import requests

with open('broken.ics', 'rb') as f:
    data = f.read()

res = requests.post(
    'https://api.correctics.com/v1/autofix',
    headers={'Content-Type': 'text/calendar'},
    data=data,
)

with open('fixed.ics', 'wb') as f:
    f.write(res.content)

print('Saved fixed.ics')

8. Validating ICS Files in CI (GitHub Actions)

Ideal for SaaS teams exporting ICS files. Add a CI step to ensure your ICS output is always valid.

.github/workflows/ics-check.yml

name: Validate ICS Files
on: [push]
jobs:
  check-ics:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Validate ICS
        run: |
          for f in ./ics/*.ics; do
            echo "Checking $f"
            curl -s -X POST https://api.correctics.com/v1/validate \
              -H "Content-Type: text/calendar" \
              --data-binary @$f \
              | grep '"valid":false' && exit 1 || true
          done

This prevents invalid exports from reaching production.


9. Bulk Validation (Directory of ICS Files)

Bash

mkdir -p fixed
for f in *.ics; do
  echo "Fixing $f"
  curl -s -X POST https://api.correctics.com/v1/autofix \
    -H "Content-Type: text/calendar" \
    --data-binary @$f \
    -o "fixed/$f"
done

Node

import fs from 'fs';

const files = fs.readdirSync('./ics');
for (const file of files) {
  const data = fs.readFileSync(`./ics/${file}`);
  const res = await fetch('https://api.correctics.com/v1/autofix', {
    method: 'POST',
    headers: { 'Content-Type': 'text/calendar' },
    body: data,
  });
  fs.writeFileSync(`./fixed/${file}`, await res.text());
}

10. Common ICS issues this catches automatically

CorrectICS automatically detects and fixes:

  • invalid time zones (e.g., TZID=EST)
  • missing END:VEVENT / END:VCALENDAR
  • missing DTSTART or DTEND
  • invalid or infinite RRULEs
  • missing UIDs
  • bad line folding or encoding
  • files with mixed line endings
  • invalid UTF-8 characters

No more manual debugging.


11. When to integrate ICS autofix

You should add automated ICS validation when:

  • users upload ICS from many vendors
  • your SaaS exports ICS for calendar integrations
  • you generate recurring events
  • you import ICS from booking apps, CRMs, POS systems
  • you sync with Outlook, Apple Calendar, Google Calendar
  • you have calendar support tickets caused by broken files

If you see recurring complaints around time zones or recurring events, programmatic validation solves it permanently.


12. Conclusion

ICS issues are persistent, subtle, and vary across calendar platforms. Validating and autofixing ICS files programmatically:

  • saves engineering time
  • reduces user-facing errors
  • prevents silent failures in Google/Outlook/Apple
  • improves export/import reliability
  • makes ICS integrations predictable

To get started:

👉 Try CorrectICS to validate or autofix ICS files →
👉 Use the API for CI, ingestion, or export pipelines