JSON and CSV Event Data to Subscribable ICS Feed Publisher avatar

JSON and CSV Event Data to Subscribable ICS Feed Publisher

Pricing

from $10.00 / 1,000 calendar publisheds

Go to Apify Store
JSON and CSV Event Data to Subscribable ICS Feed Publisher

JSON and CSV Event Data to Subscribable ICS Feed Publisher

Turn JSON or CSV event rows into a subscribable ICS feed with stable UIDs and SEQUENCE.

Pricing

from $10.00 / 1,000 calendar publisheds

Rating

0.0

(0)

Developer

kingii98

kingii98

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Categories

Share

This Actor turns a list of events into an RFC 5545 ICS feed. People can subscribe to the feed in a calendar app.

The Actor keeps each event UID stable. It increases SEQUENCE only when an event really changes. Calendar apps then update the event and do not duplicate it.

Input

FieldDescription
sourceUrlPublic HTTPS URL of a JSON array or CSV file. Maximum 5 MB and 2,000 events.
eventsInline JSON array of event objects. Maximum 2,000 events. The Actor uses it when sourceUrl is empty.
fieldMapMaps event fields to your column names. Keys: title, start, end, allDay, location, description, url, id.
defaultTimeZoneIANA time zone for times that have no offset. Default: UTC.
calendarNameCalendar name. Default: Events.
storeNameNamed key-value store for the feed. Use the same name on each run. Default: ics-feed-publisher.

Every field has a default. A run with empty input succeeds. It publishes two sample events.

Time rules

  • A date such as 2026-11-14 gives an all-day event. The end date of an all-day event is inclusive.
  • A date-time without an offset uses defaultTimeZone. The feed stores times in UTC.
  • A missing end gives a default end (1 hour, or 1 day for all-day events).

Output

  • Key-value store (storeName): calendar.ics is the feed. STATE holds the map of source id to UID, content hash, and SEQUENCE.
  • Dataset: one row per event with uid, status, sequence, and warnings. One summary row has the counts and the subscriptionUrl.

Status values:

  • new: the event is not in the saved state.
  • updated: the content changed. SEQUENCE increased by 1.
  • unchanged: no change. UID and SEQUENCE stay the same.
  • removed: the event left the source. The feed keeps it as STATUS:CANCELLED with a higher SEQUENCE.
  • skipped: the event is not valid or has a duplicate id. The Actor does not put it in the feed.

Warnings: missing end, end before start, invalid time zone, invalid end, missing title.

The event id field gives the stable identity. If a row has no id, the Actor uses a hash of title and start. A changed title or start then looks like a new event. Use an id column when you can.

Subscribe

Copy subscriptionUrl from the summary row into your calendar app. Anyone who has the URL can read the feed. Do not put private data in it.

Pricing (pay-per-event)

EventWhen the Actor chargesPrice
calendar-publishedOnce per run, after the ICS file is written to the key-value store.$0.01
event-writtenOnce for each valid event that the Actor writes to the feed. Skipped events and cancelled events do not count.$0.0002

A run with a bad input or an unreachable source publishes no feed. The Actor does not charge for that run. The run still succeeds. The summary row shows status: "error" and the reason.

Safety limits

  • HTTP only. The Actor uses no browser, proxy, or paid API.
  • HTTPS on port 443 only. No credentials in the URL.
  • The Actor rejects private, loopback, link-local, and other reserved addresses. It checks each redirect.
  • Maximum 3 redirects, 5 MB, and 2,000 events. Each network read can take 20 seconds. The whole fetch can take 30 seconds.
  • Limit: the Actor checks the address before the request. It cannot fully stop DNS rebinding between the check and the request.

Development

uv run pytest
uv run ruff check .