Skip to main content

Creating and updating resources

Write endpoints accept a flat JSON body of camelCase fields — there is no resource wrapper. Send Content-Type: application/json and put the fields at the top level of the body:

{
"name": "Tuesday Night Jazz",
"category": "Concerts"
}

Not { "event": { "name": "…" } }. References to other resources are passed by their public identifier — a category by name, a location by its id, an uploaded image by its signed id (see File uploads).

Create vs. update: how null and omitted fields differ

This is the single most important rule for writes, and it differs between POST and PATCH:

  • POST (create) — omitting a field is identical to sending null. The resource is created with that field's default (or left empty). There is no way, and no need, to distinguish the two on create.
  • PATCH (update) — a partial update. Only the fields present in the body change. Omitting a field leaves its current value untouched; sending null explicitly clears it (resets it to its default). This is the only way to tell "leave this alone" apart from "reset this."
Body on PATCHEffect
Field absentValue unchanged
"field": "new value"Value replaced
"field": nullValue cleared / reset to default

For example, to clear an event's description without touching anything else:

PATCH /2025_06/events/{id}
{ "description": null }

Sending {} to a PATCH is a valid no-op.

Timestamps must be absolute instants

Any timestamp you send — an occurrence's startsAt / endsAt, for instance — must be ISO 8601 with an explicit UTC offset or Z. A naive, zone-less time (2026-06-01T19:00:00) is rejected with 422 (startsAt must include a timezone offset).

The value is stored as the exact instant you submit. An event's timezone field is an IANA zone name that controls display only — it does not shift the instant you sent.

Validation errors

A body that is understood but fails validation returns 422 Unprocessable Entity with a per-field errors array. Field names are camelCase, matching what you sent:

{
"object": "error",
"status": 422,
"message": "Validation failed",
"errors": [
{ "field": "name", "message": "can't be blank" },
{ "field": "startsAt", "message": "must include a timezone offset" }
]
}

Errors that aren't tied to a single field omit field and carry only a message.

Destructive writes

Deletes and cancellations have extra rules — when work happens asynchronously, and why side-effect choices (emailing attendees, refunding) must be explicit. See Async, destructive, and idempotent operations.

See also