All nodes/Integrations/Calendar

Put Calendar Event

PUT iCalendar resource (create without etag, update with If-Match).

Put Calendar Event▶
CalDAV connectionOutcome
Error

Type in the graph: calendar_put_event

Exec

An error output can be enabled to handle failures on their own path.

Ports can be split into separate execution and data handles.

Try it

Minimal working scenario

Entry
Put Calendar Event▶
CalDAV Config
Exit▶
  • Execute
  • Data
  • Execute + Data
Press “Copy nodes”, open the editor and hit Ctrl+V on the canvas.

Pick your own connection or knowledge base first — the graph carries REPLACE_ME.

When to use it

Creates a calendar resource, or replaces one outright. To change a field or two on an existing event, use Patch Calendar Event: the write here overwrites the object completely, and anything absent from the body disappears from the event.

How it works

The body is composed from the fields — “Title” and “Starts at” are required — or taken ready-made from “iCalendar body”. A non-empty raw body always wins, whatever the “Event body” switch says: clear it to go back to the builder.

The builder supplies UID and DTSTAMP when they are missing; without those properties servers reject the event. A time with no offset is treated as UTC, while a filled-in time zone keeps it local and sends it with a TZID. “All-day event” writes dates instead of times. The recurrence rule is given without the property name (FREQ=WEEKLY;BYDAY=MO;COUNT=10); a rule without FREQ is refused before the request.

“Event href” is the resource path. For a new event pick a free path inside the collection, ending in .ics.

A blank ETag means “create, or overwrite unconditionally”. A non-blank one becomes a condition: if the event changed since the token was issued the server answers 412 and the node stops with error_code PRECONDITION_FAILED. The output carries href and etag — the new one, as assigned by the server; when the server sends none, the node re-reads the resource. A create → update chain uses {{ nodes.<put>.output.etag }}.

Common mistakes

  • Writing to an existing address erases fields. Attendees, description, recurrence — anything missing from the body you sent is gone. Targeted edits are what the patch node is for.
  • A blank UID means a new event. Even at the same address: to update an existing one, supply its UID from Get Calendar Event.
  • Attendees in the body are not invitations. The ATTENDEE property notifies nobody; delivery is the job of Calendar Schedule, through the outbox.
  • A body invented by a model. Generated iCalendar usually lacks UID and DTSTAMP, and the server refuses it. Let the model fill separate fields and let the node build the body.
  • An empty etag in the output. A rare server returns no token, neither in the response nor on a re-read; the next update then has to go without a conflict check.

Inputs

PortWirePayloadNotes
CalDAV connectioncalendar_storeDatadata—

required

Outputs

PortWirePayloadNotes
OutcomeoutputExecute + Dataexecute_dataobject
Erroron_errorExecute + Dataexecute_data—

shown when expose_error_output = true

Configuration

FieldTypeDefaultDescription
CalDAV connectionconnection_idstring""

Saved workspace CalDAV connection, so a simple calendar scenario does not need a separate CalDAV connection node. A node wired to the 'CalDAV connection' port wins over this field.

connection: caldavoverridden by port: calendar_store

Event hrefhrefstring""

Path or absolute URL of the calendar object, exactly as returned by Calendar Query or Calendar Multiget ({{ nodes.<query>.output.events[0].href }}). A relative path is resolved against the connection's base URL. Example: /remote.php/dav/calendars/user/personal/9f1c-1234.ics Leave it empty for a new event built from the fields and the node names the resource after the event's UID; with raw iCalendar the path is required (a new path ending in .ics). Fill it in to update an existing event — writing to a path that already holds an event REPLACES that event.

supports templates

Event bodybody_modestringfields

How the iCalendar body is produced: from the fields below, or from a raw iCalendar document. A non-empty raw body is used regardless of this setting.

Options: fields — Build from fields, raw — Raw iCalendar

Titlesummarystring""

Event title (SUMMARY). Required when building from fields.

supports templates

shown when «Event body» = Build from fields

Starts atdtstartstring""

Start, ISO 8601 (2026-07-01T10:00:00Z), or a plain date (2026-07-01) for an all-day event. Required when building from fields.

supports templates

shown when «Event body» = Build from fields

Ends atdtendstring""

End, ISO 8601. Empty means the server decides the duration.

supports templates

shown when «Event body» = Build from fields

All-day eventall_daybooleanfalse

Write DTSTART/DTEND as dates (VALUE=DATE) instead of times.

shown when «Event body» = Build from fields

Locationlocationstring""

Free-form place (LOCATION), e.g. a room name or a meeting link.

supports templates

shown when «Event body» = Build from fields

Descriptiondescriptionstring""

Event body text (DESCRIPTION).

supports templates

shown when «Event body» = Build from fields

iCalendar bodyicsstring""

Raw iCalendar document (VCALENDAR with one VEVENT). Takes precedence over the fields above whenever it is non-empty, so clear it to go back to the builder. Must carry UID and DTSTAMP — servers reject events without them.

supports templates

Advanced
ETagetagstring""

Optimistic-concurrency token from a previous Get/Query/Put on the same resource. Empty = create the resource (or overwrite it unconditionally). If the resource changed since the token was issued the server answers 412 and the node fails with error_code=PRECONDITION_FAILED. The Put/Patch nodes return the NEW etag, so a create → update chain uses {{ nodes.<put>.output.etag }}.

supports templates

Time zonetimezone_idstring""

IANA time zone for times given without an offset, e.g. Europe/Moscow. Empty = treat such times as UTC.

supports templates

shown when «Event body» = Build from fields

Recurrence rulerrulestring""

RFC 5545 RRULE without the property name, e.g. FREQ=WEEKLY;BYDAY=MO;COUNT=10. Empty = a single occurrence.

supports templates

shown when «Event body» = Build from fields

Attendeesattendeesstring""

Email addresses, comma- or newline-separated. Written as ATTENDEE properties.

supports templates

shown when «Event body» = Build from fields

Organizerorganizerstring""

Organizer email address (ORGANIZER). Required by most servers for invitations.

supports templates

shown when «Event body» = Build from fields

Event UIDevent_uidstring""

Stable identifier of the event. Empty = generate one. Reuse the UID of an existing event to update or cancel it.

supports templates

shown when «Event body» = Build from fields

Statusevent_statusstringnone

Event STATUS. 'Not set' leaves the property out of the event.

Options: none — Not set, CONFIRMED — Confirmed, TENTATIVE — Tentative, CANCELLED — Cancelled

shown when «Event body» = Build from fields

Shared fields

Every node has these three — the platform adds them, not the node author.

  • expose_error_output — When enabled, show an execution output to connect nodes that run if this step fails.
  • split_ports_in — Show separate execution and data input handles instead of one combined port.
  • split_ports_out — Show separate execution and data output handles instead of one combined port.

Ready-made examples using this node