Skip to content

API: Events

Endpoints for managing events.

Base path

/events

Endpoints

POST /events

Create a new event with one or more photos. The backend generates R2 object keys and presigned URLs for each photo. The client uploads files directly to R2 using the returned presigned URLs after receiving the response.

Request:

LocationFieldTypeRequiredDescription
bodynamestringyesEvent name (max 255 chars)
bodydescriptionstringnoOptional event description
bodydatestring (ISO 8601)yesEvent date and time with timezone
bodyphotosobject[]yesArray of photo objects (min 1). Each: { name: string, mimeType: string }. Allowed mimeTypes: image/png, image/jpeg

Response:

StatusDescriptionBody
201Event created{ id, name, description, date, photos: [{ id, url, presignedUrl }] }
400Validation error{ message: string }

Business rules:

  • date must not be in the past.
  • At least one photo is required.
  • mimeType must be one of: image/png, image/jpeg.
  • photos[].url in the response is the full public URL (R2_PUBLIC_URL + object_key).
  • photos[].presignedUrl is a temporary presigned URL for the client to upload the file directly to R2 via PUT.

GET /events

List all events with their photos, ordered by date descending (most recent first).

Request:

LocationFieldTypeRequiredDescription
No parameters

Response:

StatusDescriptionBody
200Event list{ events: [{ id, name, description, date, photos: [{ id, url }] }] }

Response fields:

FieldTypeDescription
events[].idnumberEvent ID
events[].namestringEvent name
events[].descriptionstring | nullOptional event description
events[].datestring (ISO 8601)Event date and time with timezone
events[].photos[].idnumberPhoto ID
events[].photos[].urlstringFull public URL (R2_PUBLIC_URL + object_key)

Business rules:

  • Returns all non-deleted events (soft-deleted events are excluded).
  • Events are sorted by date descending.
  • Each event includes all its associated photos.
  • photos[].url is the full public URL, same as in the create response (no presignedUrl here).