Push a calendar calfeed cannot reach

Some calendars cannot be polled: a work account behind single sign-on, an internal tool, a script's output. A push source turns that around — your side uploads a JSON dump, calfeed stores it under the source's sharing settings, and it shows up in views and feeds like any other source.

  1. Create the source. + Add source → in the account picker choose Push (curl a JSON dump). Name it, set a short id and a timezone (the fallback for times in the dump that carry none), pick what it shares, and click Create push source.
  2. Copy the URL. The source card shows it with a ready curl line. The URL is the credential: whoever holds it can write this source. Lost it? show URL on the card brings it back; new push URL replaces it and kills the old one.
  3. Optionally lock it down. edit the source → Required headers on upload, e.g. X-Push-Key=secret123, and/or Allowed IPs/CIDRs for the machine that uploads. From then on the URL alone gets 403; the card's curl line includes the -H flag.
  4. Upload.
    curl -H 'X-Push-Key: secret123' -T dump.json https://calfeed.io/v1/push/<token>
    Each upload replaces the previous one. The reply says what happened: {"stored": 41, "dropped": {"outside_window": 2, "cancelled": 1}}. A rejected event fails the whole upload and names the offending ids, so a bad dump never half-replaces a good one.
  5. Add it to a view. Tick the source (or its tag) in the views that should show it; sources never join views on their own.

The dump

Google Calendar's event shape, so most exporters already speak it:

{
  "source_timezone": "America/Los_Angeles",
  "events": [
    {
      "id": "abc_20260911T173500Z",
      "start": {"dateTime": "2026-09-11T10:35:00-07:00", "timeZone": "America/Los_Angeles"},
      "end":   {"dateTime": "2026-09-11T11:30:00-07:00", "timeZone": "America/Los_Angeles"},
      "summary": "Informal discussion",
      "x-responseStatus": "accepted",
      "x-attendeeCount": 13,
      "x-conferencing": {"video": true, "type": "zoom"}
    },
    {"id": "holiday", "summary": "Company holiday",
     "start": {"date": "2026-09-14"}, "end": {"date": "2026-09-15"}}
  ]
}

Only id, start and end are required; everything else is optional and unknown keys are ignored. All-day events use date (end exclusive), timed ones dateTime with an offset or a timeZone. status: "cancelled" drops an event. Send x-responseStatus and views hide what you declined. Add window_start/window_end to replace only that span, so a daily 7-day dump never wipes what a wider one stored. Limits: 5,000 events, 2 MB. The full contract with every corner case lives in the repo's test/fixtures/calendar-sample.json.

Privacy

Two layers: what your exporter puts in the dump, then the source's sharing settings. A dump with only titles, times and attendee counts, stored under a grant of the same, means nothing more ever lands in calfeed.

← all tutorials