openapi: 3.1.0 info: title: Events Manager REST API version: 7.2.3.1 description: | REST API exposed by the Events Manager WordPress plugin. Source of truth: active `register_rest_route()` calls in `classes/uploads/em-uploads-api.php` and `classes/api/em-api-rest.php`. contact: name: Pixelite url: https://pixelite.com license: name: GPL-2.0-or-later identifier: GPL-2.0-or-later servers: - url: "{site_url}/wp-json" description: WordPress REST API root. variables: site_url: default: https://example.com description: Base URL of the WordPress site. tags: - name: Uploads description: Temporary upload, revert, and load helpers used by Events Manager forms. - name: Events description: Event list, read, validation, availability, create, update, and delete operations. - name: Locations description: Location list, read, validation, create, update, and delete operations. - name: Bookings description: Booking list, read, validation, create, update, status, and delete operations. - name: Categories description: Events Manager event category term operations. - name: Tags description: Events Manager event tag term operations. paths: /events-manager/v1/uploads: get: operationId: loadUpload summary: Load uploaded file description: | Loads a previously uploaded temporary file by `temp_id`. On success, the endpoint streams file bytes with a dynamic content type instead of JSON. tags: [Uploads] security: - cookieAuth: [] - basicAuth: [] parameters: - $ref: "#/components/parameters/TempId" - $ref: "#/components/parameters/XFilenames" responses: "200": $ref: "#/components/responses/UploadFileContentResponse" "400": $ref: "#/components/responses/BadRequest" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" "500": $ref: "#/components/responses/ServerError" post: operationId: uploadFile summary: Upload file description: | Accepts a multipart form upload, validates it through Events Manager upload filters, stores it temporarily, and returns a temporary file ID plus a revert nonce. tags: [Uploads] security: - cookieAuth: [] - basicAuth: [] parameters: - $ref: "#/components/parameters/UploadPath" - $ref: "#/components/parameters/XEMNonce" requestBody: $ref: "#/components/requestBodies/UploadMultipart" responses: "200": $ref: "#/components/responses/UploadResponse" "400": $ref: "#/components/responses/BadRequest" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" "500": $ref: "#/components/responses/ServerError" delete: operationId: revertUpload summary: Revert upload description: | Deletes a temporary upload created by the upload endpoint. The callback expects the temporary file ID and the nonce returned by `uploadFile`. tags: [Uploads] security: - cookieAuth: [] - basicAuth: [] parameters: - $ref: "#/components/parameters/TmpFile" - $ref: "#/components/parameters/UploadNonce" responses: "200": $ref: "#/components/responses/UploadRevertResponse" "400": $ref: "#/components/responses/BadRequest" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" "500": $ref: "#/components/responses/ServerError" /events-manager/v1/events: get: operationId: listEvents summary: List events description: | Returns a paginated collection of events matching the supplied Events Manager search filters. Public requests are limited to readable published events. tags: [Events] security: - cookieAuth: [] - basicAuth: [] parameters: - $ref: "#/components/parameters/Page" - $ref: "#/components/parameters/PerPage" - $ref: "#/components/parameters/Search" - $ref: "#/components/parameters/Context" - $ref: "#/components/parameters/Scope" - $ref: "#/components/parameters/EventStatus" - $ref: "#/components/parameters/ActiveStatus" - $ref: "#/components/parameters/Cancelled" - $ref: "#/components/parameters/Active" - $ref: "#/components/parameters/CategoryFilter" - $ref: "#/components/parameters/TagFilter" - $ref: "#/components/parameters/LocationFilter" - $ref: "#/components/parameters/LocationIdFilter" - $ref: "#/components/parameters/Town" - $ref: "#/components/parameters/State" - $ref: "#/components/parameters/Country" - $ref: "#/components/parameters/Region" - $ref: "#/components/parameters/Near" - $ref: "#/components/parameters/NearUnit" - $ref: "#/components/parameters/NearDistance" - $ref: "#/components/parameters/EventType" - $ref: "#/components/parameters/EventArchetype" - $ref: "#/components/parameters/OrderBy" - $ref: "#/components/parameters/Order" - $ref: "#/components/parameters/Blog" - $ref: "#/components/parameters/Private" - $ref: "#/components/parameters/PrivateOnly" - $ref: "#/components/parameters/Timeslots" responses: "200": $ref: "#/components/responses/EventCollectionResponse" "400": $ref: "#/components/responses/BadRequest" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" "500": $ref: "#/components/responses/ServerError" post: operationId: createEvent summary: Create event description: | Creates an Events Manager event using the shared API service. The user must have the Events Manager event editing capability; publishing depends on the user's publish capability. tags: [Events] security: - cookieAuth: [] - basicAuth: [] requestBody: $ref: "#/components/requestBodies/EventInput" responses: "201": $ref: "#/components/responses/EventCreatedResponse" "400": $ref: "#/components/responses/BadRequest" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" "500": $ref: "#/components/responses/ServerError" /events-manager/v1/events/validate: post: operationId: validateEvent summary: Validate event description: | Validates event input without saving it. This is intended as a safe preflight endpoint for UI flows and AI agents before creating or updating an event. tags: [Events] security: - cookieAuth: [] - basicAuth: [] requestBody: $ref: "#/components/requestBodies/EventInput" responses: "200": $ref: "#/components/responses/EventValidationResponse" "400": $ref: "#/components/responses/BadRequest" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" "500": $ref: "#/components/responses/ServerError" /events-manager/v1/events/{event_id}/availability: get: operationId: getEventAvailability summary: Get event availability description: | Returns booking availability, event-wide spaces, and per-ticket availability for a readable event. The endpoint does not create or reserve spaces. tags: [Events] security: - cookieAuth: [] - basicAuth: [] parameters: - $ref: "#/components/parameters/EventId" responses: "200": $ref: "#/components/responses/EventAvailabilityResponse" "400": $ref: "#/components/responses/BadRequest" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" "500": $ref: "#/components/responses/ServerError" /events-manager/v1/events/{event_id}: get: operationId: getEvent summary: Get event description: | Retrieves one event by Events Manager event ID. Timeslot-specific IDs may use the `event_id:timeslot_id` format accepted by the route pattern. tags: [Events] security: - cookieAuth: [] - basicAuth: [] parameters: - $ref: "#/components/parameters/EventId" - $ref: "#/components/parameters/Context" responses: "200": $ref: "#/components/responses/EventResponse" "400": $ref: "#/components/responses/BadRequest" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" "500": $ref: "#/components/responses/ServerError" patch: operationId: updateEvent summary: Update event description: | Partially updates an existing event. Validation and Events Manager capability checks run before the event is saved. tags: [Events] security: - cookieAuth: [] - basicAuth: [] parameters: - $ref: "#/components/parameters/EventId" requestBody: $ref: "#/components/requestBodies/EventInput" responses: "200": $ref: "#/components/responses/EventResponse" "400": $ref: "#/components/responses/BadRequest" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" "500": $ref: "#/components/responses/ServerError" delete: operationId: deleteEvent summary: Delete event description: | Deletes or trashes an event, depending on the Events Manager object behavior and the `force` query parameter. The response includes the previous serialized event data. tags: [Events] security: - cookieAuth: [] - basicAuth: [] parameters: - $ref: "#/components/parameters/EventId" - $ref: "#/components/parameters/Force" responses: "200": $ref: "#/components/responses/DeleteEventResponse" "400": $ref: "#/components/responses/BadRequest" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" "500": $ref: "#/components/responses/ServerError" /events-manager/v1/locations: get: operationId: listLocations summary: List locations description: | Returns a paginated collection of Events Manager locations matching the supplied filters. Public requests are limited to readable published locations. tags: [Locations] security: - cookieAuth: [] - basicAuth: [] parameters: - $ref: "#/components/parameters/Page" - $ref: "#/components/parameters/PerPage" - $ref: "#/components/parameters/Search" - $ref: "#/components/parameters/Context" - $ref: "#/components/parameters/Scope" - $ref: "#/components/parameters/EventStatus" - $ref: "#/components/parameters/Eventful" - $ref: "#/components/parameters/Eventless" - $ref: "#/components/parameters/CategoryFilter" - $ref: "#/components/parameters/TagFilter" - $ref: "#/components/parameters/Town" - $ref: "#/components/parameters/State" - $ref: "#/components/parameters/Country" - $ref: "#/components/parameters/Region" - $ref: "#/components/parameters/Near" - $ref: "#/components/parameters/NearUnit" - $ref: "#/components/parameters/NearDistance" - $ref: "#/components/parameters/OrderBy" - $ref: "#/components/parameters/Order" - $ref: "#/components/parameters/Blog" - $ref: "#/components/parameters/Private" - $ref: "#/components/parameters/PrivateOnly" responses: "200": $ref: "#/components/responses/LocationCollectionResponse" "400": $ref: "#/components/responses/BadRequest" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" "500": $ref: "#/components/responses/ServerError" post: operationId: createLocation summary: Create location description: | Creates a physical Events Manager location. The user must have Events Manager location editing permissions; publishing depends on the user's publish capability. tags: [Locations] security: - cookieAuth: [] - basicAuth: [] requestBody: $ref: "#/components/requestBodies/LocationInput" responses: "201": $ref: "#/components/responses/LocationCreatedResponse" "400": $ref: "#/components/responses/BadRequest" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" "500": $ref: "#/components/responses/ServerError" /events-manager/v1/locations/countries: get: operationId: listLocationCountries summary: List location countries description: | Returns countries with their ISO-3166 alpha-2 code and translated display name. By default the full ISO-3166 country list is returned — useful for populating a country picker on a fresh install with no locations yet, or any UI that needs every country WordPress knows about. Pass `only_available=true` to narrow the result to countries that have at least one stored location row. This is the right mode for answering *"what countries do I have events in?"*. tags: [Locations] security: - cookieAuth: [] - basicAuth: [] parameters: - name: only_available in: query description: When `true`, only return countries with at least one stored location. Defaults to `false` (full ISO list). schema: type: boolean default: false example: true - name: search in: query description: Optional case-insensitive substring filter against the country code or its display name. schema: type: string example: united responses: "200": $ref: "#/components/responses/LocationCountryListResponse" "401": $ref: "#/components/responses/Unauthorized" "500": $ref: "#/components/responses/ServerError" /events-manager/v1/locations/regions: get: operationId: listLocationRegions summary: List location regions description: | Returns the distinct list of region names present in the Events Manager locations table. Pass `country` to narrow the result to a single country. tags: [Locations] security: - cookieAuth: [] - basicAuth: [] parameters: - $ref: "#/components/parameters/Country" - name: search in: query description: Optional case-insensitive substring filter against the region name. schema: type: string responses: "200": $ref: "#/components/responses/LocationGeoListResponse" "401": $ref: "#/components/responses/Unauthorized" "500": $ref: "#/components/responses/ServerError" /events-manager/v1/locations/states: get: operationId: listLocationStates summary: List location states description: | Returns the distinct list of state/province names present in the Events Manager locations table. Pass `country` and/or `region` to narrow the result. tags: [Locations] security: - cookieAuth: [] - basicAuth: [] parameters: - $ref: "#/components/parameters/Country" - $ref: "#/components/parameters/Region" - name: search in: query description: Optional case-insensitive substring filter against the state name. schema: type: string responses: "200": $ref: "#/components/responses/LocationGeoListResponse" "401": $ref: "#/components/responses/Unauthorized" "500": $ref: "#/components/responses/ServerError" /events-manager/v1/locations/towns: get: operationId: listLocationTowns summary: List location towns description: | Returns the distinct list of town/city names present in the Events Manager locations table. Pass `country`, `region`, and/or `state` to narrow the result. tags: [Locations] security: - cookieAuth: [] - basicAuth: [] parameters: - $ref: "#/components/parameters/Country" - $ref: "#/components/parameters/Region" - $ref: "#/components/parameters/State" - name: search in: query description: Optional case-insensitive substring filter against the town name. schema: type: string responses: "200": $ref: "#/components/responses/LocationGeoListResponse" "401": $ref: "#/components/responses/Unauthorized" "500": $ref: "#/components/responses/ServerError" /events-manager/v1/locations/validate: post: operationId: validateLocation summary: Validate location description: | Validates location input without saving it. This is intended as a safe preflight endpoint before creating or updating a location. tags: [Locations] security: - cookieAuth: [] - basicAuth: [] requestBody: $ref: "#/components/requestBodies/LocationInput" responses: "200": $ref: "#/components/responses/LocationValidationResponse" "400": $ref: "#/components/responses/BadRequest" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" "500": $ref: "#/components/responses/ServerError" /events-manager/v1/locations/{location_id}: get: operationId: getLocation summary: Get location description: | Retrieves one Events Manager location by ID. The `edit` context requires location management permission. tags: [Locations] security: - cookieAuth: [] - basicAuth: [] parameters: - $ref: "#/components/parameters/LocationId" - $ref: "#/components/parameters/Context" responses: "200": $ref: "#/components/responses/LocationResponse" "400": $ref: "#/components/responses/BadRequest" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" "500": $ref: "#/components/responses/ServerError" patch: operationId: updateLocation summary: Update location description: | Partially updates an existing location. Validation and Events Manager capability checks run before the location is saved. tags: [Locations] security: - cookieAuth: [] - basicAuth: [] parameters: - $ref: "#/components/parameters/LocationId" requestBody: $ref: "#/components/requestBodies/LocationInput" responses: "200": $ref: "#/components/responses/LocationResponse" "400": $ref: "#/components/responses/BadRequest" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" "500": $ref: "#/components/responses/ServerError" delete: operationId: deleteLocation summary: Delete location description: | Deletes or trashes a location, depending on object behavior and the `force` query parameter. The response includes the previous serialized location data. tags: [Locations] security: - cookieAuth: [] - basicAuth: [] parameters: - $ref: "#/components/parameters/LocationId" - $ref: "#/components/parameters/Force" responses: "200": $ref: "#/components/responses/DeleteLocationResponse" "400": $ref: "#/components/responses/BadRequest" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" "500": $ref: "#/components/responses/ServerError" /events-manager/v1/bookings: get: operationId: listBookings summary: List bookings description: | Returns bookings visible to the current user. Regular logged-in users are scoped to their own bookings; booking managers may query broader booking collections. tags: [Bookings] security: - cookieAuth: [] - basicAuth: [] parameters: - $ref: "#/components/parameters/Page" - $ref: "#/components/parameters/PerPage" - $ref: "#/components/parameters/Search" - name: scope in: query description: | Filter bookings by their event's date using an Events Manager date scope — `future`, `past`, `today`, `tomorrow`, `this-week`, `this-month`, `next-month`, `all`, or a `YYYY-MM-DD,YYYY-MM-DD` range. Omit to include bookings for events of any date. schema: type: string example: future - $ref: "#/components/parameters/Context" - $ref: "#/components/parameters/BookingEvent" - $ref: "#/components/parameters/BookingEventId" - $ref: "#/components/parameters/BookingStatus" - $ref: "#/components/parameters/RsvpStatus" - $ref: "#/components/parameters/Person" - $ref: "#/components/parameters/TicketId" - $ref: "#/components/parameters/BookingIdFilter" - $ref: "#/components/parameters/OrderBy" - $ref: "#/components/parameters/Order" - $ref: "#/components/parameters/Blog" - $ref: "#/components/parameters/TimeslotId" responses: "200": $ref: "#/components/responses/BookingCollectionResponse" "400": $ref: "#/components/responses/BadRequest" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" "500": $ref: "#/components/responses/ServerError" post: operationId: createBooking summary: Create booking description: | Creates a booking for an event using ticket-space selections. Anonymous booking creation is disabled by default in the service unless explicitly enabled by the plugin filter. tags: [Bookings] security: - cookieAuth: [] - basicAuth: [] requestBody: $ref: "#/components/requestBodies/BookingInput" responses: "201": $ref: "#/components/responses/BookingCreatedResponse" "400": $ref: "#/components/responses/BadRequest" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" "500": $ref: "#/components/responses/ServerError" /events-manager/v1/bookings/validate: post: operationId: validateBooking summary: Validate booking description: | Validates booking input without saving it. Availability, ticket, and required guest data checks run through the Events Manager booking objects. tags: [Bookings] security: - cookieAuth: [] - basicAuth: [] requestBody: $ref: "#/components/requestBodies/BookingInput" responses: "200": $ref: "#/components/responses/BookingValidationResponse" "400": $ref: "#/components/responses/BadRequest" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" "500": $ref: "#/components/responses/ServerError" /events-manager/v1/bookings/{booking_id}: get: operationId: getBooking summary: Get booking description: | Retrieves one booking by ID if the booking is visible to the current user. Booking managers may view managed bookings; regular users may view their own bookings. tags: [Bookings] security: - cookieAuth: [] - basicAuth: [] parameters: - $ref: "#/components/parameters/BookingId" - $ref: "#/components/parameters/Context" responses: "200": $ref: "#/components/responses/BookingResponse" "400": $ref: "#/components/responses/BadRequest" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" "500": $ref: "#/components/responses/ServerError" patch: operationId: updateBooking summary: Update booking description: | Partially updates ticket selections, comments, guest details, and other supported booking fields. Booking management permission is required. tags: [Bookings] security: - cookieAuth: [] - basicAuth: [] parameters: - $ref: "#/components/parameters/BookingId" requestBody: $ref: "#/components/requestBodies/BookingInput" responses: "200": $ref: "#/components/responses/BookingResponse" "400": $ref: "#/components/responses/BadRequest" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" "500": $ref: "#/components/responses/ServerError" delete: operationId: deleteBooking summary: Delete booking description: | Permanently deletes a booking and its ticket bookings. The response includes the previous serialized booking data. tags: [Bookings] security: - cookieAuth: [] - basicAuth: [] parameters: - $ref: "#/components/parameters/BookingId" responses: "200": $ref: "#/components/responses/DeleteBookingResponse" "400": $ref: "#/components/responses/BadRequest" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" "500": $ref: "#/components/responses/ServerError" /events-manager/v1/bookings/{booking_id}/status: post: operationId: setBookingStatus summary: Set booking status description: | Changes a booking status, such as pending, approved, rejected, or cancelled. The operation may send booking status email notifications unless `send_email` is false. tags: [Bookings] security: - cookieAuth: [] - basicAuth: [] parameters: - $ref: "#/components/parameters/BookingId" requestBody: $ref: "#/components/requestBodies/BookingStatusInput" responses: "200": $ref: "#/components/responses/BookingResponse" "400": $ref: "#/components/responses/BadRequest" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" "500": $ref: "#/components/responses/ServerError" /events-manager/v1/media: post: operationId: uploadMedia summary: Upload media description: | Uploads an image (or other media) to the WordPress media library and returns the resulting attachment metadata. Three input shapes are accepted — pick the one that matches your client: - **URL sideload** — `{ source_url: "https://..." }`. Public URL is fetched and stored. Good for AI agents pulling stock images. - **Base64 inline** — `{ filename, mime_type, content_base64 }`. Bytes are decoded and stored. - **Multipart** — standard `multipart/form-data` with a `file` field. Returns `{ id, url, mime_type, title, alt_text, width, height }`. The `id` can be passed straight to `featured_image` on events/locations or `image` on categories/tags. Requires the `upload_files` capability. tags: [Media] security: - cookieAuth: [] - basicAuth: [] requestBody: $ref: "#/components/requestBodies/MediaUploadInput" responses: "201": $ref: "#/components/responses/MediaResponse" "400": $ref: "#/components/responses/BadRequest" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "500": $ref: "#/components/responses/ServerError" /events-manager/v1/categories: get: operationId: listCategories summary: List categories description: | Returns paginated Events Manager event category terms. Category routes are generated from the plugin's active term route map. tags: [Categories] security: - cookieAuth: [] - basicAuth: [] parameters: - $ref: "#/components/parameters/Page" - $ref: "#/components/parameters/PerPage" - $ref: "#/components/parameters/Search" - $ref: "#/components/parameters/HideEmpty" responses: "200": $ref: "#/components/responses/TermCollectionResponse" "400": $ref: "#/components/responses/BadRequest" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" "500": $ref: "#/components/responses/ServerError" post: operationId: createCategory summary: Create category description: | Creates an Events Manager event category term. Requires Events Manager term management permission. tags: [Categories] security: - cookieAuth: [] - basicAuth: [] requestBody: $ref: "#/components/requestBodies/TermInput" responses: "201": $ref: "#/components/responses/TermCreatedResponse" "400": $ref: "#/components/responses/BadRequest" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" "500": $ref: "#/components/responses/ServerError" /events-manager/v1/categories/{term_id}: get: operationId: getCategory summary: Get category description: | Retrieves one Events Manager event category term by term ID. tags: [Categories] security: - cookieAuth: [] - basicAuth: [] parameters: - $ref: "#/components/parameters/TermId" responses: "200": $ref: "#/components/responses/TermResponse" "400": $ref: "#/components/responses/BadRequest" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" "500": $ref: "#/components/responses/ServerError" patch: operationId: updateCategory summary: Update category description: | Partially updates an Events Manager event category term. Requires Events Manager term management permission. tags: [Categories] security: - cookieAuth: [] - basicAuth: [] parameters: - $ref: "#/components/parameters/TermId" requestBody: $ref: "#/components/requestBodies/TermInput" responses: "200": $ref: "#/components/responses/TermResponse" "400": $ref: "#/components/responses/BadRequest" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" "500": $ref: "#/components/responses/ServerError" delete: operationId: deleteCategory summary: Delete category description: | Deletes an Events Manager event category term. The response includes the previous serialized term data. tags: [Categories] security: - cookieAuth: [] - basicAuth: [] parameters: - $ref: "#/components/parameters/TermId" responses: "200": $ref: "#/components/responses/DeleteTermResponse" "400": $ref: "#/components/responses/BadRequest" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" "500": $ref: "#/components/responses/ServerError" /events-manager/v1/tags: get: operationId: listTags summary: List tags description: | Returns paginated Events Manager event tag terms. Tag routes are generated from the plugin's active term route map. tags: [Tags] security: - cookieAuth: [] - basicAuth: [] parameters: - $ref: "#/components/parameters/Page" - $ref: "#/components/parameters/PerPage" - $ref: "#/components/parameters/Search" - $ref: "#/components/parameters/HideEmpty" responses: "200": $ref: "#/components/responses/TermCollectionResponse" "400": $ref: "#/components/responses/BadRequest" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" "500": $ref: "#/components/responses/ServerError" post: operationId: createTag summary: Create tag description: | Creates an Events Manager event tag term. Requires Events Manager term management permission. tags: [Tags] security: - cookieAuth: [] - basicAuth: [] requestBody: $ref: "#/components/requestBodies/TermInput" responses: "201": $ref: "#/components/responses/TermCreatedResponse" "400": $ref: "#/components/responses/BadRequest" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" "500": $ref: "#/components/responses/ServerError" /events-manager/v1/tags/{term_id}: get: operationId: getTag summary: Get tag description: | Retrieves one Events Manager event tag term by term ID. tags: [Tags] security: - cookieAuth: [] - basicAuth: [] parameters: - $ref: "#/components/parameters/TermId" responses: "200": $ref: "#/components/responses/TermResponse" "400": $ref: "#/components/responses/BadRequest" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" "500": $ref: "#/components/responses/ServerError" patch: operationId: updateTag summary: Update tag description: | Partially updates an Events Manager event tag term. Requires Events Manager term management permission. tags: [Tags] security: - cookieAuth: [] - basicAuth: [] parameters: - $ref: "#/components/parameters/TermId" requestBody: $ref: "#/components/requestBodies/TermInput" responses: "200": $ref: "#/components/responses/TermResponse" "400": $ref: "#/components/responses/BadRequest" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" "500": $ref: "#/components/responses/ServerError" delete: operationId: deleteTag summary: Delete tag description: | Deletes an Events Manager event tag term. The response includes the previous serialized term data. tags: [Tags] security: - cookieAuth: [] - basicAuth: [] parameters: - $ref: "#/components/parameters/TermId" responses: "200": $ref: "#/components/responses/DeleteTermResponse" "400": $ref: "#/components/responses/BadRequest" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" "500": $ref: "#/components/responses/ServerError" components: x-example-values: event: &event_value name: Summer Pottery Workshop id: "123" type: single post_id: 456 parent: null owner: guest: false name: Events Team slug: summer-pottery-workshop status: 0 content: Learn hand-building basics in a relaxed studio session. bookings: end_date: "2026-07-10" end_time: "17:00:00" rsvp_spaces: 4 spaces: 24 when: all_day: false start: "2026-07-12T00:00:00Z" start_date: "2026-07-12" start_time: "10:00:00" end: "2026-07-12T03:00:00Z" end_date: "2026-07-12" end_time: "13:00:00" timezone: Australia/Sydney location: name: Harbour Studio id: 45 post_id: 222 owner: 1 status: 1 slug: harbour-studio content: Accessible studio space near Circular Quay. geo: latitude: -33.861 longitude: 151.21 address: address: 12 Workshop Lane town: Sydney region: New South Wales state: NSW postcode: "2000" country: AU recurrence: false recurring: false language: en translation: 0 location: &location_value name: Harbour Studio id: 45 parent: null post_id: 222 owner: 1 status: 1 slug: harbour-studio content: Accessible studio space near Circular Quay. geo: latitude: -33.861 longitude: 151.21 address: address: 12 Workshop Lane town: Sydney region: New South Wales state: NSW postcode: "2000" country: AU language: en translation: 0 booking: &booking_value id: 789 event_id: "123" uuid: 7f7d9e11c8d8460a8aa5f2c4c58f4020 person_id: 23 status: 1 spaces: 2 price: "98.00" tax_rate: 0.1 taxes: "8.91" comment: Please seat us near the front. meta: {} tickets: "55": name: General Admission description: Standard workshop ticket. spaces: 2 price: "98.00" attendees: - uuid: 9d5d1c8e4b7a4c3ab2c078d557bbcd11 price: "49.00" meta: {} - uuid: 7c0d2b2a01244ecfa5fdbf91da555111 price: "49.00" meta: {} datetime: "2026-05-19T02:15:00Z" person: guest: false email: ada@example.com name: Ada Lovelace phone: "+61400111222" term: &term_value id: 12 name: Workshops slug: workshops taxonomy: event-categories description: Hands-on learning events. parent: 0 count: 8 color: "#80b538" image_url: https://example.com/wp-content/uploads/workshops.jpg url: https://example.com/events/categories/workshops/ securitySchemes: cookieAuth: type: apiKey in: header name: X-WP-Nonce description: WordPress REST nonce for cookie-authenticated requests. basicAuth: type: http scheme: basic description: WordPress Application Passwords over HTTP Basic Authentication. emUploadNonce: type: apiKey in: header name: X-EM-Nonce description: Events Manager upload nonce used by the upload endpoint. parameters: Page: name: page in: query description: Page number for paginated collection responses. schema: type: integer minimum: 1 default: 1 PerPage: name: per_page in: query description: Number of items to return per page. The service caps this at 100. schema: type: integer minimum: 1 maximum: 100 default: 20 Search: name: search in: query description: Free-text search term. schema: type: string example: workshop Context: name: context in: query description: Response context. `edit` may expose management metadata and requires object permissions. schema: type: string enum: [view, edit, embed] default: view EventId: name: event_id in: path required: true description: Events Manager event ID. Timeslot-specific IDs may use `event_id:timeslot_id`. schema: type: string pattern: "^\\d+(?::\\d+)?$" example: "123" LocationId: name: location_id in: path required: true description: Events Manager location ID. schema: type: integer format: int64 example: 45 BookingId: name: booking_id in: path required: true description: Events Manager booking ID (integer) or booking UUID (32-character hex string). schema: oneOf: - type: integer format: int64 example: 789 - type: string pattern: "^[0-9a-f]{32}$" example: fab91000f7e149dea28baa7f2bafcabf TermId: name: term_id in: path required: true description: WordPress term ID. schema: type: integer format: int64 example: 12 Force: name: force in: query description: Whether to force deletion where supported by the underlying object. schema: type: boolean default: false Scope: name: scope in: query description: Events Manager date scope such as `future`, `past`, `today`, or a date range. schema: type: string default: future example: future EventStatus: name: status in: query description: Events Manager event/location publish status filter. schema: oneOf: - type: integer - type: string example: 1 ActiveStatus: name: active_status in: query description: Event active status filter. schema: oneOf: - type: integer - type: string example: 1 Cancelled: name: cancelled in: query description: Include or exclude cancelled events. schema: type: boolean Active: name: active in: query description: Include active events. schema: type: boolean CategoryFilter: name: category in: query description: Category ID, slug, or comma-separated category filter. schema: oneOf: - type: integer - type: string example: workshops TagFilter: name: tag in: query description: Tag ID, slug, or comma-separated tag filter. schema: oneOf: - type: integer - type: string example: training LocationFilter: name: location in: query description: Location ID or comma-separated location IDs. schema: oneOf: - type: integer - type: string example: 45 LocationIdFilter: name: location_id in: query description: Location ID alias accepted by Events Manager search defaults. schema: type: integer format: int64 example: 45 Town: name: town in: query description: Location town/city filter. schema: type: string example: Sydney State: name: state in: query description: Location state filter. schema: type: string example: NSW Country: name: country in: query description: Location country filter, usually a country code. schema: type: string example: AU Region: name: region in: query description: Location region filter. schema: type: string example: New South Wales Near: name: near in: query description: Latitude/longitude pair used by geo search. schema: type: string example: "-33.8688,151.2093" NearUnit: name: near_unit in: query description: Unit for geo distance. schema: type: string enum: [mi, km] example: km NearDistance: name: near_distance in: query description: Distance from the `near` coordinates. schema: type: integer minimum: 1 example: 25 EventType: name: event_type in: query description: Events Manager event type. schema: type: string enum: [single, recurring, repeating, recurrence] example: single EventArchetype: name: event_archetype in: query description: Event archetype/custom post type filter. schema: type: string example: event OrderBy: name: orderby in: query description: Field or comma-separated fields used for ordering. schema: type: string example: event_start_date,event_start_time Order: name: order in: query description: Sort direction. schema: type: string enum: [ASC, DESC, asc, desc] example: ASC Blog: name: blog in: query description: Multisite blog ID filter when global tables are enabled. schema: oneOf: - type: integer - type: string example: 1 Private: name: private in: query description: Include private objects when the current user can read them. schema: type: boolean PrivateOnly: name: private_only in: query description: Only return private objects. schema: type: boolean Timeslots: name: timeslots in: query description: Split matching events by timeslot where Events Manager timeslots are enabled. schema: type: boolean Eventful: name: eventful in: query description: Only return locations that have associated events. schema: type: boolean Eventless: name: eventless in: query description: Only return locations that do not have associated events. schema: type: boolean BookingEvent: name: event in: query description: Booking event filter. Timeslot IDs may use `event_id:timeslot_id`. schema: type: string example: "123" BookingEventId: name: event_id in: query description: Alias for the booking event filter. schema: type: string example: "123" BookingStatus: name: status in: query description: Booking status filter. Multiple statuses may be comma-separated. schema: oneOf: - type: integer - type: string example: "0,1" RsvpStatus: name: rsvp_status in: query description: Booking RSVP status filter. schema: oneOf: - type: integer - type: string example: 1 Person: name: person in: query description: Person/user ID filter. Non-managers are scoped to their own user ID. schema: type: integer format: int64 example: 23 TicketId: name: ticket_id in: query description: Ticket ID filter. schema: type: integer format: int64 example: 55 BookingIdFilter: name: booking_id in: query description: Booking ID or comma-separated booking IDs. schema: oneOf: - type: integer - type: string example: 789 TimeslotId: name: timeslot_id in: query description: Timeslot ID filter. schema: type: integer format: int64 example: 7 HideEmpty: name: hide_empty in: query description: Hide terms with no assigned posts. schema: type: boolean default: false TempId: name: temp_id in: query required: true description: Temporary upload ID returned by the upload endpoint. schema: type: string example: phpA1b2C3 XFilenames: name: X-Filenames in: header description: Optional JSON map of temporary file IDs to original filenames. schema: type: string example: '{"phpA1b2C3":{"name":"venue-map.png"}}' UploadPath: name: path in: query required: true description: Upload validation path used for Events Manager nonce and filters. schema: type: string example: event-image XEMNonce: name: X-EM-Nonce in: header required: true description: Nonce generated for `em_uploads_api/{path}`. schema: type: string example: 91f4a2d8bc TmpFile: name: tmp_file in: query required: true description: Temporary upload ID to revert. schema: type: string example: phpA1b2C3 UploadNonce: name: nonce in: query required: true description: Revert nonce returned by the upload endpoint. schema: type: string example: a7b6c5d4e3 requestBodies: UploadMultipart: required: true content: multipart/form-data: schema: $ref: "#/components/schemas/UploadRequest" examples: eventImage: summary: Upload an event image value: file: ./event-banner.jpg EventInput: required: true content: application/json: schema: $ref: "#/components/schemas/EventInput" examples: workshop: summary: Create a workshop event value: name: Summer Pottery Workshop content: Learn hand-building basics in a relaxed studio session. type: single post_status: publish when: start_date: "2026-07-12" start_time: "10:00:00" end_date: "2026-07-12" end_time: "13:00:00" timezone: Australia/Sydney all_day: false location_id: 45 categories: [12] tags: [34] LocationInput: required: true content: application/json: schema: $ref: "#/components/schemas/LocationInput" examples: venue: summary: Create a physical venue value: name: Harbour Studio content: Accessible studio space near Circular Quay. post_status: publish address: address: 12 Workshop Lane town: Sydney state: NSW postcode: "2000" region: New South Wales country: AU geo: latitude: -33.861 longitude: 151.21 BookingInput: required: true content: application/json: schema: $ref: "#/components/schemas/BookingInput" examples: attendeeBooking: summary: Book two spaces value: event_id: "123" comment: Please seat us near the front. tickets: - ticket_id: 55 spaces: 2 person: name: Ada Lovelace email: ada@example.com phone: "+61400111222" send_email: true BookingStatusInput: required: true content: application/json: schema: $ref: "#/components/schemas/BookingStatusInput" examples: approveBooking: summary: Approve a booking value: status: 1 send_email: true ignore_spaces: false TermInput: required: true content: application/json: schema: $ref: "#/components/schemas/TermInput" examples: workshopCategory: summary: Create a workshop category value: name: Workshops slug: workshops description: Hands-on learning events. parent: 0 MediaUploadInput: required: true content: application/json: schema: $ref: "#/components/schemas/MediaUploadInput" examples: sideloadUrl: summary: Sideload an image from a public URL value: source_url: https://images.unsplash.com/photo-1556909114-f6e7ad7d3136 title: Knitting workshop hero alt_text: Person knitting with a teal yarn ball inlineBase64: summary: Inline base64 upload value: filename: hero.jpg mime_type: image/jpeg content_base64: /9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcUFhYaHSUfGhsjHBYWICwgIyYnKSopGR8tMC0oMCUoKSj/... existingId: summary: Look up an existing attachment value: id: 12345 multipart/form-data: schema: type: object properties: file: type: string format: binary description: The file to upload. title: type: string alt_text: type: string post_id: type: integer required: [file] responses: BadRequest: description: Invalid request. content: application/json: schema: $ref: "#/components/schemas/WPError" examples: invalid: $ref: "#/components/examples/BadRequestError" Unauthorized: description: Authentication is required or invalid. content: application/json: schema: $ref: "#/components/schemas/WPError" examples: unauthorized: $ref: "#/components/examples/UnauthorizedError" Forbidden: description: The authenticated user cannot perform this action. content: application/json: schema: $ref: "#/components/schemas/WPError" examples: forbidden: $ref: "#/components/examples/ForbiddenError" NotFound: description: The requested object was not found. content: application/json: schema: $ref: "#/components/schemas/WPError" examples: notFound: $ref: "#/components/examples/NotFoundError" ServerError: description: An unexpected server error occurred. content: application/json: schema: $ref: "#/components/schemas/WPError" examples: serverError: $ref: "#/components/examples/ServerError" UploadResponse: description: Temporary file upload was accepted. content: application/json: schema: $ref: "#/components/schemas/UploadResponse" examples: uploaded: value: success: true file: id: phpA1b2C3 name: event-banner.jpg size: 184233 type: image/jpeg nonce: a7b6c5d4e3 UploadRevertResponse: description: Temporary file revert result. content: application/json: schema: $ref: "#/components/schemas/MessageResponse" examples: reverted: value: success: true message: File deleted. UploadFileContentResponse: description: Raw file contents. content: application/octet-stream: schema: $ref: "#/components/schemas/UploadedFileContent" examples: file: value: raw file bytes omitted EventCollectionResponse: description: Paginated events. headers: X-WP-Total: $ref: "#/components/headers/XWPTotal" X-WP-TotalPages: $ref: "#/components/headers/XWPTotalPages" content: application/json: schema: $ref: "#/components/schemas/EventCollection" examples: events: $ref: "#/components/examples/EventCollectionExample" EventResponse: description: Event response. content: application/json: schema: $ref: "#/components/schemas/Event" examples: event: $ref: "#/components/examples/EventExample" EventCreatedResponse: description: Event was created. content: application/json: schema: $ref: "#/components/schemas/Event" examples: event: $ref: "#/components/examples/EventExample" EventValidationResponse: description: Event validation result. content: application/json: schema: $ref: "#/components/schemas/EventValidation" examples: valid: value: valid: true event: *event_value EventAvailabilityResponse: description: Event availability response. content: application/json: schema: $ref: "#/components/schemas/EventAvailability" examples: availability: $ref: "#/components/examples/EventAvailabilityExample" DeleteEventResponse: description: Event delete response. content: application/json: schema: $ref: "#/components/schemas/DeleteEventResponse" examples: deleted: value: deleted: true previous: *event_value LocationCollectionResponse: description: Paginated locations. headers: X-WP-Total: $ref: "#/components/headers/XWPTotal" X-WP-TotalPages: $ref: "#/components/headers/XWPTotalPages" content: application/json: schema: $ref: "#/components/schemas/LocationCollection" examples: locations: $ref: "#/components/examples/LocationCollectionExample" LocationResponse: description: Location response. content: application/json: schema: $ref: "#/components/schemas/Location" examples: location: $ref: "#/components/examples/LocationExample" LocationCreatedResponse: description: Location was created. content: application/json: schema: $ref: "#/components/schemas/Location" examples: location: $ref: "#/components/examples/LocationExample" LocationCountryListResponse: description: Distinct list of countries present in the locations table. content: application/json: schema: type: object properties: items: type: array items: type: object properties: code: type: string description: ISO-3166 alpha-2 country code. example: GB name: type: string description: Translated display name for the country. example: United Kingdom required: [code, name] example: items: - code: AU name: Australia - code: GB name: United Kingdom - code: US name: United States LocationGeoListResponse: description: Distinct list of region / state / town values present in the locations table. content: application/json: schema: type: object properties: items: type: array items: type: string example: items: - London - Manchester - Edinburgh LocationValidationResponse: description: Location validation result. content: application/json: schema: $ref: "#/components/schemas/LocationValidation" examples: valid: value: valid: true location: *location_value DeleteLocationResponse: description: Location delete response. content: application/json: schema: $ref: "#/components/schemas/DeleteLocationResponse" examples: deleted: value: deleted: true previous: *location_value BookingCollectionResponse: description: Paginated bookings. headers: X-WP-Total: $ref: "#/components/headers/XWPTotal" X-WP-TotalPages: $ref: "#/components/headers/XWPTotalPages" content: application/json: schema: $ref: "#/components/schemas/BookingCollection" examples: bookings: $ref: "#/components/examples/BookingCollectionExample" MediaResponse: description: Newly created (or looked-up) media library attachment. content: application/json: schema: $ref: "#/components/schemas/Attachment" example: id: 12345 url: https://example.com/wp-content/uploads/2026/06/hero.jpg mime_type: image/jpeg title: Knitting workshop hero alt_text: Person knitting with a teal yarn ball width: 1920 height: 1080 BookingResponse: description: Booking response. content: application/json: schema: $ref: "#/components/schemas/Booking" examples: booking: $ref: "#/components/examples/BookingExample" BookingCreatedResponse: description: Booking was created. content: application/json: schema: $ref: "#/components/schemas/Booking" examples: booking: $ref: "#/components/examples/BookingExample" BookingValidationResponse: description: Booking validation result. content: application/json: schema: $ref: "#/components/schemas/BookingValidation" examples: valid: value: valid: true booking: *booking_value DeleteBookingResponse: description: Booking delete response. content: application/json: schema: $ref: "#/components/schemas/DeleteBookingResponse" examples: deleted: value: deleted: true previous: *booking_value TermCollectionResponse: description: Paginated terms. headers: X-WP-Total: $ref: "#/components/headers/XWPTotal" X-WP-TotalPages: $ref: "#/components/headers/XWPTotalPages" content: application/json: schema: $ref: "#/components/schemas/TermCollection" examples: terms: $ref: "#/components/examples/TermCollectionExample" TermResponse: description: Term response. content: application/json: schema: $ref: "#/components/schemas/Term" examples: term: $ref: "#/components/examples/TermExample" TermCreatedResponse: description: Term was created. content: application/json: schema: $ref: "#/components/schemas/Term" examples: term: $ref: "#/components/examples/TermExample" DeleteTermResponse: description: Term delete response. content: application/json: schema: $ref: "#/components/schemas/DeleteTermResponse" examples: deleted: value: deleted: true previous: *term_value headers: XWPTotal: description: Total number of matching items. schema: type: integer example: 42 XWPTotalPages: description: Total number of result pages. schema: type: integer example: 3 schemas: WPError: type: object required: [code, message, data] properties: code: type: string example: em_api_event_not_found message: type: string example: Event not found. data: type: object required: [status] properties: status: type: integer example: 404 additionalProperties: true MessageResponse: type: object required: [success] properties: success: type: boolean message: type: string error: type: string additionalProperties: true UploadRequest: type: object required: [file] properties: file: type: string format: binary description: File upload. The callback supports deeply nested upload arrays but expects one uploaded file. UploadResponse: type: object required: [success, file, nonce] properties: success: type: boolean file: $ref: "#/components/schemas/UploadFile" nonce: type: string description: Nonce used to revert this temporary upload. UploadFile: type: object required: [id, name, size, type] properties: id: type: string name: type: string size: type: integer type: type: string UploadedFileContent: type: string format: binary description: Raw file bytes. Pagination: type: object required: [total, total_pages, page, per_page] properties: total: type: integer total_pages: type: integer page: type: integer per_page: type: integer EventCollection: type: object required: [items, pagination] properties: items: type: array items: $ref: "#/components/schemas/Event" pagination: $ref: "#/components/schemas/Pagination" Event: type: object required: [name, id, type, post_id, slug, status, content, bookings, when, location, recurring] properties: name: type: string id: type: string description: Events Manager event ID. Timeslot contexts may use `event_id:timeslot_id`. type: type: string enum: [single, recurring, repeating] post_id: type: - integer - "null" parent: type: - integer - "null" owner: $ref: "#/components/schemas/Owner" blog_id: type: - integer - "null" group_id: type: - integer - "null" slug: type: string status: type: - integer - "null" description: "TODO: `EM_Event::to_api()` currently maps this from `event_private`; confirm intended meaning before freezing docs." content: type: string image: description: Featured image URLs (thumbnail + full), or null if the event has no image. type: - object - "null" properties: thumbnail: type: string format: uri full: type: string format: uri bookings: $ref: "#/components/schemas/EventBookings" when: $ref: "#/components/schemas/EventWhen" location: anyOf: - $ref: "#/components/schemas/Location" - $ref: "#/components/schemas/EventLocation" - type: boolean location_type: type: string recurrence: oneOf: - $ref: "#/components/schemas/GenericObject" - type: boolean recurrences: $ref: "#/components/schemas/GenericObject" recurring: type: boolean language: type: - string - "null" translation: type: - integer - "null" timeslot_id: type: integer featured_image: oneOf: - $ref: "#/components/schemas/Attachment" - type: "null" description: Featured image attachment, or `null` if none is set. permissions: $ref: "#/components/schemas/Permissions" additionalProperties: true EventInput: type: object description: | Event create/update payload. Top-level field names mirror the live admin/public form $_POST contract so the same shape works across `EM_Event::get_post()`, MCP abilities, and REST. Pro overlay fields are marked `::pro::`. Extras pass through verbatim — see `additionalProperties` at the bottom of the schema for the policy on undocumented keys. required: - event_name - event_start_date properties: event_name: type: string description: Event display title. **Required.** content: type: string description: Long-form event description. Accepts HTML, sanitized by `wp_kses` against the post-content allowlist. event_type: type: string enum: [single, recurring, repeating] description: Event timing model. `single` is one occurrence; `recurring` is a parent that generates child occurrences; `repeating` is a parent CPT for separately-tracked instances. Defaults to `single`. event_archetype: type: string description: Custom event-archetype CPT slug (configured under Events > Settings > Archetypes). Defaults to the base event type. post_status: type: string enum: [publish, pending, draft, private] description: WP post status. Setting `publish` requires the `publish_events` capability; without it, EM saves as `pending` regardless. featured_image: $ref: "#/components/schemas/ImageAssignmentInput" description: WordPress featured image for the event. Sets `_thumbnail_id` on the underlying CPT. Accepts an attachment ID, public URL (sideloaded), media-upload object, or `null` to clear. featured_image_alt: type: string description: Alt text applied to the featured image attachment (`_wp_attachment_image_alt`). Only takes effect when `featured_image` is also provided. event_start_date: type: string format: date description: Event start date in ISO format (`YYYY-MM-DD`). **Required.** event_end_date: type: string format: date description: Event end date. Defaults to `event_start_date` if omitted. event_start_time: type: string pattern: "^([01]\\d|[0-9]|2[0-3])(:[0-5]\\d)?(:[0-5]\\d)?( ?(AM|PM))?$" description: | Event start time. Accepted forms: `HH:MM`, `HH:MM:SS`, or 12-hour `h:MM AM/PM`. API-friendly alias for `event_timeranges[0].start` — translated server-side. If both this and `event_timeranges` are sent, the explicit nested value wins per-field. event_end_time: type: string pattern: "^([01]\\d|[0-9]|2[0-3])(:[0-5]\\d)?(:[0-5]\\d)?( ?(AM|PM))?$" description: Event end time (same formats as `event_start_time`). Alias for `event_timeranges[0].end`. event_rsvp_date: type: string format: date description: Booking cut-off date (no bookings accepted after this date). event_rsvp_time: type: string pattern: "^([01]\\d|[0-9]|2[0-3])(:[0-5]\\d)?(:[0-5]\\d)?( ?(AM|PM))?$" description: Booking cut-off time of day, partnering with `event_rsvp_date`. event_timezone: type: string description: IANA timezone (e.g. `Europe/London`). Defaults to the site timezone if omitted. event_all_day: type: boolean description: When true, EM clears `start`/`end` times and treats the event as all-day. Alias for `event_timeranges[0].all_day`. event_timeranges: type: array description: | Canonical EM time-range structure (mirrors the live event form). Index 0 holds the primary range; additional indices are timeslot generators when `timeslots: true` is set. Sending `event_start_time` / `event_end_time` / `event_all_day` at the top level is translated into this shape — pick whichever style suits the consumer. items: type: object properties: start: type: string description: Start of the range. Accepts `HH:MM`, `HH:MM:SS`, or `h:MM AM/PM`. end: type: string description: End of the range, same formats as `start`. all_day: description: Presence sets this range to all-day; clears `start`/`end`. oneOf: - type: boolean - type: string timeslots: description: When set, this range generates repeated timeslots using `duration` / `buffer` / `frequency` below. oneOf: - type: boolean - type: string duration: type: object description: Length of each generated timeslot. properties: qty: { type: integer, description: Quantity. } unit: { type: string, enum: [M, H, D], description: 'Minutes / Hours / Days.' } buffer: type: object description: Gap between consecutive timeslots. properties: qty: { type: integer } unit: { type: string, enum: [M, H, D] } frequency: type: object description: Repeat interval between timeslots. properties: qty: { type: integer } unit: { type: string, enum: [M, H, D] } event_rsvp: type: integer description: Bookings master switch — `1` to enable, `0` to disable. **Must be `1` for `em_tickets` to take effect** (mirrors the admin-form bookings checkbox). event_rsvp_spaces: type: integer description: Per-booking maximum spaces. `0` = no per-booking cap. event_spaces: type: integer minimum: 0 description: Total event capacity across all tickets. `0` = no event-wide cap. event_active_status: type: integer description: Active-status code (1 = active, 0 = cancelled/inactive; see `EM_Event::get_active_statuses()` for the full enum). event_private: type: integer description: Privacy flag — `1` = private (visible only to users with `read_private_events`), `0` = public. location_id: type: integer description: | Existing location ID to bind. Leave empty (and supply `location_name` plus address fields) to create a new location inline during this event save. location_name: type: string description: Inline location create — used only when `location_id` is empty. location_address: type: string description: Inline location create — street address. location_town: type: string description: Inline location create — town / city. location_state: type: string description: Inline location create — state / county. location_postcode: type: string description: Inline location create — postal / ZIP code. location_region: type: string description: Inline location create — free-form region label, used for filtering. location_country: type: string description: Inline location create — ISO 3166-1 alpha-2 country code (e.g. `GB`, `US`). location_latitude: type: number description: Inline location create — WGS-84 latitude. location_longitude: type: number description: Inline location create — WGS-84 longitude. location_type: type: string description: Location type. Default `location` (physical, uses `location_id` or inline fields). `::pro::` values include `url` and `online`. location_url: type: string description: '`::pro::` URL for url-type locations.' event_location_url: type: string description: '`::pro::` Legacy event URL field (predates `location_url`).' event_location_url_text: type: string description: '`::pro::` Display text for `event_location_url`.' event_categories: type: array description: Category term IDs. Canonical name matches the live event form $_POST contract. items: type: integer event_tags: type: array description: Tag term IDs. items: type: integer categories: type: array description: '*Deprecated.* Alias for `event_categories`. Kept for back-compat.' items: type: integer tags: type: array description: '*Deprecated.* Alias for `event_tags`.' items: type: integer em_tickets: type: object description: | Tickets bound to this event. Object keyed by ticket ID (existing) or 1-based sequential index (new). Key `0` is reserved by `EM_Tickets::get_post()` (admin-form template row); the API auto-shifts 0-indexed payloads. **Requires `event_rsvp: 1`** on the event to take effect — sending tickets without bookings enabled is silently ignored (matches the admin-form behaviour). additionalProperties: $ref: "#/components/schemas/TicketInput" em_attributes: type: object description: | Custom event attributes, keyed by attribute label as configured under Events > Settings > Attributes. Values are typically strings; select-multiple attributes accept an array of strings. additionalProperties: true em_coupons: type: array description: '`::pro::` Coupon IDs to bind to this event (event-wide discounts).' items: type: integer waitlist: type: integer description: '`::pro::` (waitlists) `1` enables the waitlist on this event, `0` disables.' waitlist_booking_limit: type: integer description: '`::pro::` (waitlists) Maximum spaces a single waitlist booking may request.' waitlist_expiry: type: string description: '`::pro::` (waitlists) Minutes before an offered waitlist slot lapses if not confirmed.' waitlist_limit: type: integer description: '`::pro::` (waitlists) Maximum total waitlist size.' rsvp_policy: type: string description: '`::pro::` (rsvp-policy) Deadline / cancel policy slug.' rsvp_policy_type: type: string description: '`::pro::` (rsvp-policy) Policy enforcement type.' bookings_can_cancel: type: string description: '`::pro::` Whether attendees may self-cancel their bookings.' bookings_can_cancel_time: type: string description: '`::pro::` Cancel cut-off as an ISO 8601 duration before event start (e.g. `P1D` = 1 day before).' minimum_capacity_spaces: type: integer description: '`::pro::` Minimum bookings required by the `minimum_capacity_time` deadline; if not met, EM can cancel automatically.' minimum_capacity_time: type: string description: '`::pro::` ISO 8601 duration before event start by which `minimum_capacity_spaces` must be met.' dependent_event: type: string description: '`::pro::` Prerequisite event UID or ID — bookers must have a booking on that event first.' custom_attendee_form: type: integer description: '`::pro::` (bookings-form) Form ID overriding the default attendee form for this event.' custom_booking_form: type: integer description: '`::pro::` (bookings-form) Form ID overriding the default booking form.' recurrence_rsvp_days: type: integer description: '`::pro::` Per-recurrence RSVP cut-off offset (days). Used with `recurrence_rsvp_days_when`.' recurrence_rsvp_days_when: type: string description: '`::pro::` `before` or `after`, qualifies `recurrence_rsvp_days`.' data_privacy_consent: type: boolean description: Privacy-policy acknowledgement, required when the privacy add-on is configured to enforce it. data_comms_consent: type: boolean description: Marketing/comms opt-in. additionalProperties: description: | Any extra field name accepted by `EM_Event::get_post()` / `EM_Event::get_post_meta()` — or by callbacks hooking into those methods (Pro add-ons, custom plugins, theme code). Documented properties above are the canonical core set; everything else passes through to `$_REQUEST` unchanged. EventWhen: type: object required: [all_day, start, start_date, start_time, end, end_date, end_time, timezone] properties: all_day: type: boolean start: type: string format: date-time start_date: type: string format: date start_time: type: string end: type: string format: date-time end_date: type: string format: date end_time: type: string timezone: type: string EventBookings: type: object properties: end_date: type: - string - "null" format: date end_time: type: - string - "null" rsvp_spaces: type: - integer - "null" spaces: type: - integer - "null" booked_spaces: type: - integer - "null" description: Confirmed booked spaces. Populated for booking-enabled events only. available_spaces: type: - integer - "null" description: Spaces still available. Populated for booking-enabled events only. EventAvailability: type: object required: [event_id, bookings_enabled, open, spaces, available_spaces, tickets] properties: event_id: type: string bookings_enabled: type: boolean open: type: boolean spaces: type: integer available_spaces: type: integer tickets: type: array items: $ref: "#/components/schemas/TicketAvailability" TicketAvailability: type: object required: [id, name, price, spaces, available_spaces, available] properties: id: type: integer name: type: string description: type: - string - "null" price: oneOf: - type: number - type: string spaces: type: integer available_spaces: type: integer available: type: boolean EventValidation: type: object required: [valid, event] properties: valid: type: boolean event: $ref: "#/components/schemas/Event" LocationCollection: type: object required: [items, pagination] properties: items: type: array items: $ref: "#/components/schemas/Location" pagination: $ref: "#/components/schemas/Pagination" Location: type: object required: [name, id, post_id, slug, status, content, geo, address] properties: name: type: string id: type: integer parent: type: - integer - "null" post_id: type: - integer - "null" blog_id: type: - integer - "null" owner: type: - integer - "null" status: type: - integer - "null" slug: type: string content: type: string geo: $ref: "#/components/schemas/Geo" address: $ref: "#/components/schemas/Address" image: description: Featured image URLs (thumbnail + full), or null if the location has no image. type: - object - "null" properties: thumbnail: type: string format: uri full: type: string format: uri upcoming_events_count: type: - integer - "null" description: Number of upcoming (future-scope) events at this location. language: type: - string - "null" translation: type: - integer - "null" featured_image: oneOf: - $ref: "#/components/schemas/Attachment" - type: "null" description: Featured image attachment, or `null` if none is set. permissions: $ref: "#/components/schemas/Permissions" additionalProperties: true LocationInput: type: object description: | Location create/update payload. Top-level field names mirror the live admin/public form $_POST contract. Extras pass through via `additionalProperties` — see the policy at the bottom of the schema. required: - location_name - location_address - location_town - location_country properties: location_name: type: string description: Display name of the venue. **Required.** content: type: string description: Long-form venue description. Accepts HTML, sanitized by `wp_kses`. post_status: type: string enum: [publish, pending, draft, private] description: WP post status. `publish` requires the `publish_locations` capability. featured_image: $ref: "#/components/schemas/ImageAssignmentInput" description: WordPress featured image for the location. Sets `_thumbnail_id` on the underlying CPT. Accepts an attachment ID, public URL (sideloaded), media-upload object, or `null` to clear. featured_image_alt: type: string description: Alt text applied to the featured image attachment (`_wp_attachment_image_alt`). Only takes effect when `featured_image` is also provided. location_address: type: string description: Street address. **Required.** location_town: type: string description: Town or city. **Required.** location_state: type: string description: State, province, or county. location_postcode: type: string description: Postal or ZIP code. location_region: type: string description: Region label (free-form, used for filtering). location_country: type: string description: ISO 3166-1 alpha-2 country code (e.g. `GB`, `US`). **Required.** location_latitude: type: number description: WGS-84 latitude. location_longitude: type: number description: WGS-84 longitude. em_attributes: type: object description: Custom location attributes, keyed by attribute label as configured under Events > Settings > Attributes. additionalProperties: true data_privacy_consent: type: boolean description: Privacy-policy acknowledgement, required when the privacy add-on is configured to enforce it. data_comms_consent: type: boolean description: Marketing/comms opt-in. additionalProperties: description: | Any extra field name accepted by `EM_Location::get_post()` / `EM_Location::get_post_meta()` — or by callbacks hooking into those methods. Documented properties above are the canonical core set; everything else passes through to `$_REQUEST` unchanged. Geo: type: object properties: latitude: type: number longitude: type: number Address: type: object properties: address: type: string town: type: string region: type: string state: type: string postcode: type: string country: type: string AddressInput: type: object properties: address: type: string town: type: string state: type: string postcode: type: string region: type: string country: type: string EventLocation: type: object description: Event-specific location object such as URL/webinar. Shape is supplied by event-location classes. additionalProperties: true LocationValidation: type: object required: [valid, location] properties: valid: type: boolean location: $ref: "#/components/schemas/Location" BookingCollection: type: object required: [items, pagination] properties: items: type: array items: $ref: "#/components/schemas/Booking" pagination: $ref: "#/components/schemas/Pagination" Booking: type: object required: [id, event_id, uuid, person_id, status, spaces, price, tickets, datetime, person] properties: id: type: integer event_id: type: string uuid: type: string person_id: type: integer status: type: integer description: Booking status. Common values include 0 pending, 1 approved, 2 rejected, and 3 cancelled. spaces: type: integer price: oneOf: - type: number - type: string tax_rate: type: number taxes: oneOf: - type: number - type: string comment: type: string meta: $ref: "#/components/schemas/GenericObject" tickets: type: object additionalProperties: $ref: "#/components/schemas/BookingTicket" datetime: type: string format: date-time event: $ref: "#/components/schemas/Event" person: $ref: "#/components/schemas/BookingPerson" permissions: $ref: "#/components/schemas/Permissions" additionalProperties: true BookingInput: type: object description: | Booking create/update payload. Top-level field names mirror `EM_Booking::get_post()`'s `$_REQUEST` contract — the same shape the live booking form posts. Person fields are flat (`user_name`, `user_email`, `dbem_phone`, `dbem_country`) — no `person` wrapper. Admin-only fields (`booking_status`, `booking_tax_rate`, `person_id`, `manual_booking*`, `payment_*`) are accepted in the schema but **stripped server-side for callers without the `manage_bookings` capability**, so a public consumer can't escalate by sending them. required: - event_id - em_tickets properties: event_id: type: string description: Event the booking is being made against. **Required.** em_tickets: type: object description: | Tickets being booked. Object keyed by ticket ID (the real `ticket_id`, not a positional index). Value: `{ spaces, ticket_bookings? }`. `ticket_bookings[i].attendee` carries per-attendee form-field values when the Pro `bookings-form` add-on is active. **Required** — a booking must reference at least one ticket. additionalProperties: $ref: "#/components/schemas/BookingTicketInput" user_name: type: string description: Booker's display name. Required for guest bookings (when not logged in). user_email: type: string format: email description: Booker's email address. Required for guest bookings. dbem_phone: type: string description: Booker's phone number. Legacy field name — the `dbem_` prefix matches EM core's $_POST contract. dbem_country: type: string description: Booker's country (ISO 3166-1 alpha-2). Used by some Pro forms. booking_comment: type: string description: Free-text note attached to the booking. gateway: type: string description: Payment gateway slug (e.g. `offline`, `stripe_checkout`, `paypal_advanced`). See the gateway introspection endpoint for the active list. coupon_code: type: string description: '`::pro::` Promotional discount code to apply to this booking.' waitlist: type: boolean description: '`::pro::` Set to `true` to opt this booking into the waitlist when the event is full.' waitlist_spaces: type: integer minimum: 1 description: '`::pro::` Spaces requested when joining the waitlist.' waitlist_booking_uuid: type: string description: '`::pro::` UUID of an existing waitlist booking being promoted to a real booking.' donation_amount: type: string description: '`::pro::` (donations) Optional donation added on top of the ticket cost.' extra_charge: type: string description: '`::pro::` (extra-charges) Selected extra-charge option.' terms_agreement: type: boolean description: Terms-and-conditions acknowledgement, required by the public booking form when configured. recurrence_timezone: type: string description: Timezone to interpret the booking against for a specific occurrence of a recurring event. booking: type: object description: '`::pro::` (bookings-form) Booking-form field values. Flattened into `$_REQUEST` server-side before `EM_Booking::get_post()` so the form add-on reads them under their configured field slugs.' booking_fields: type: object description: '`::pro::` (bookings-form) Alias of `booking`. Kept for back-compat with older clients.' registration: type: object description: Booking-form fields that map to WordPress user registration (name, email, etc.). Flattened into `$_REQUEST`. send_email: type: boolean description: When true (default), EM sends the configured booking-confirmation email after save. override_availability: type: boolean description: Admin-only. Bypass per-ticket availability checks (used by the admin manual-booking flow). person_id: type: integer description: Admin-only. Assigns the booking to an existing user ID instead of the logged-in caller. booking_status: type: integer description: Admin-only. Directly sets the booking status (see `BookingStatusInput.status` for the enum). booking_tax_rate: type: number description: Admin-only. Override the booking's tax rate (decimal, e.g. `0.20` = 20%). manual_booking: type: string description: Admin-only. Nonce that triggers the admin manual-booking flow (bypasses some public-form validations). manual_booking_confirm: type: boolean description: Admin-only. Confirms the booking immediately after creation. manual_booking_override: type: boolean description: Admin-only. Bypasses availability / capacity / member-only restrictions. payment_amount: type: string description: Admin-only. Record an upfront payment amount against the booking. payment_full: type: boolean description: Admin-only. Mark the booking as fully paid (skips outstanding-balance accounting). data_privacy_consent: type: boolean description: Privacy-policy acknowledgement, required when the privacy add-on is configured to enforce it. data_comms_consent: type: boolean description: Marketing/comms opt-in. additionalProperties: description: | Any extra field name accepted by `EM_Booking::get_post()` — or by callbacks hooking into that method, including the `em_booking_get_post` filter, Pro form add-ons, and custom plugins. Documented properties above are the canonical core set; everything else passes through to `$_REQUEST` unchanged. BookingTicketInput: type: object description: | Per-ticket entry inside a booking POST. EM core only reads `spaces`; the optional `ticket_bookings` array carries per-attendee form data when the Pro `bookings-form` add-on is active (it reads each entry via the `em_ticket_booking_get_post` filter). required: - spaces properties: ticket_id: type: integer description: Redundant when this object is keyed by ticket ID at the parent level. Provided for callers who prefer to set it explicitly on the body. spaces: type: integer minimum: 0 description: Number of seats to book at this ticket. Should equal `ticket_bookings.length` when per-attendee data is provided. **Required.** ticket_bookings: type: array description: | One entry per attendee. `::pro::` (bookings-form) The shape of `attendee` is freeform — its keys are the field slugs configured for the event's attendee form (Events > Booking Forms > Attendee Forms). Default slugs include `attendee_name` and `phone_number`; custom fields use whatever slug the admin set, and slugs may contain spaces (e.g. `"Beverage Choice"`). items: $ref: "#/components/schemas/BookingAttendeeInput" additionalProperties: description: | Any extra field name accepted by `EM_Ticket_Bookings::get_post()` or callbacks hooking into it. Documented properties above are the canonical core set. BookingAttendeeInput: type: object description: | `::pro::` (bookings-form) Per-attendee form payload. Wraps a single `attendee` object whose keys are the field slugs configured for the active attendee form. Field discovery: until a dedicated field-schema endpoint ships (`GET /events-manager-pro/v1/bookings/forms/attendee/{id}/fields` — roadmap), inspect the form via `GET /events-manager-pro/v1/bookings/forms/attendee/{id}` and read the `form_fields` array. Each item's `field_id` is the key to use here. The form ID attached to an event is on `bookings.forms.attendee.id` in the event response. Example shape (depends on form config): ``` { "attendee": { "attendee_name": "Alice Smith", "phone_number": "+44 20 7946 0001", "choices": ["choice-x", "choice-y"], "Beverage Choice": ["wine", "beer"], "bdate": { "start": "1990-04-12" }, "document": ["upload-tmp-id-abc123"] } } ``` properties: attendee: type: object description: Form field values keyed by the field's configured slug. See parent description for discovery. additionalProperties: description: Custom field value — type depends on the field's form-builder configuration (string, array, file-upload-id, nested date object, etc.). additionalProperties: description: Reserved for future ticket-booking-level fields beyond the `attendee` wrapper. TicketInput: type: object description: | Event ticket create/update payload. Top-level field names mirror `EM_Ticket::get_post()`'s `$_POST` contract. Used in two contexts: nested under `EventInput.em_tickets` (where the outer key identifies the row), or as the body of `/tickets/{id}` calls. required: - ticket_name properties: ticket_id: type: integer description: Existing ticket ID (omit for new tickets). When sent inside `em_tickets[]`, identifies the row to update; new tickets use a positional outer key and leave this empty. event_id: type: string description: Owning event ID. Auto-populated when the ticket is nested under an event POST/PATCH; required when sending to `/tickets/{id}` directly. ticket_name: type: string description: Ticket display name. **Required.** ticket_description: type: string description: Long-form ticket description (e.g. what's included). Accepts HTML. ticket_status: type: integer description: '`1` = bookable, `0` = disabled. **Defaults to `0` if omitted** — set explicitly to `1` to make new tickets bookable.' ticket_price: type: number description: Ticket price in the site currency. `0` = free. ticket_spaces: type: integer minimum: 0 description: Total spaces available at this ticket. `0` = unlimited (subject to `event_spaces`). ticket_min: type: integer minimum: 0 description: Minimum spaces a single booking must request at this ticket. ticket_max: type: integer minimum: 0 description: Maximum spaces a single booking may request at this ticket. `0` = inherit `event_rsvp_spaces`. ticket_required: type: boolean description: When true, every booking must include at least `ticket_min` spaces at this ticket. ticket_type: type: string enum: [members, guests] description: Audience restriction. `members` = logged-in users only (see `ticket_members_roles`); `guests` = not-logged-in only; omit for all. ticket_members_roles: type: array description: WP role slugs allowed to book when `ticket_type` is `members`. items: type: string ticket_start: type: string description: When this ticket becomes available (datetime string, partners with `ticket_start_time`). ticket_end: type: string description: When this ticket stops being available. ticket_start_time: type: string description: Time-of-day partner for `ticket_start` (same formats as `event_start_time`). ticket_end_time: type: string description: Time-of-day partner for `ticket_end`. ticket_order: type: integer description: Display sort index (lowest first). delete: type: string description: WP nonce required by `EM_Tickets::get_post()` to delete this ticket row when sent inside `em_tickets`. additionalProperties: description: | Any extra field name accepted by `EM_Ticket::get_post()` — or by callbacks hooking into it. Documented properties above are the canonical core set. BookingTicket: type: object properties: name: type: string description: type: string spaces: type: integer price: oneOf: - type: number - type: string attendees: type: array items: $ref: "#/components/schemas/BookingAttendee" BookingAttendee: type: object properties: uuid: type: string price: oneOf: - type: number - type: string meta: $ref: "#/components/schemas/GenericObject" BookingPerson: type: object required: [guest, email, name] properties: guest: type: boolean email: type: string format: email name: type: string phone: type: string BookingPersonInput: type: object properties: name: type: string email: type: string format: email phone: type: string BookingStatusInput: type: object description: | Payload for `POST /bookings/{id}/status`. Lets booking managers transition a booking between statuses (pending / approved / rejected / cancelled / waitlist states) with the option to suppress the change-notification email. required: - status properties: status: type: integer enum: [0, 1, 2, 3, 4, 5, 6, 7, 8] description: | New booking status code. **Required.** Values (from `EM_Booking::$status_array`): `0` pending, `1` approved, `2` rejected, `3` cancelled, `4` awaiting online payment, `5` offline payment, `6` waitlist confirmed, `7` waitlist pending, `8` waitlist expired. send_email: type: boolean default: true description: When true (default), sends the configured status-change email to the booker. ignore_spaces: type: boolean default: false description: When true, allow the transition even if the event's spaces are exhausted (admin override). BookingValidation: type: object required: [valid, booking] properties: valid: type: boolean booking: $ref: "#/components/schemas/Booking" TermCollection: type: object required: [items, pagination] properties: items: type: array items: $ref: "#/components/schemas/Term" pagination: $ref: "#/components/schemas/Pagination" Term: type: object required: [id, name, slug, taxonomy, description, parent, count] properties: id: type: integer name: type: string slug: type: string taxonomy: type: string enum: [event-categories, event-tags] description: type: string parent: type: integer count: type: integer color: type: - string - "null" example: "#80b538" description: Term colour stored under EM meta key `{taxonomy}-bgcolor`. Used by the EM front-end and Pro blocks to colour-code terms. image_url: type: - string - "null" format: uri description: Public URL of the term image attachment (mirror of `image.url`). Kept for backwards compatibility. image: oneOf: - $ref: "#/components/schemas/Attachment" - type: "null" description: Term image attachment with id/url/dimensions, or `null` if none is set. url: type: string format: uri description: Public archive URL for this term. additionalProperties: true TermInput: type: object description: Create/update payload for event categories and tags. required: - name properties: name: type: string description: Term display name. **Required.** slug: type: string description: URL-friendly slug. Auto-generated from `name` if omitted. description: type: string description: Long-form term description. parent: type: integer description: Parent term ID for hierarchical taxonomies (categories support nesting; tags don't). color: type: - string - "null" example: "#80b538" description: Hex colour used by the EM front-end / Pro blocks. Stored under `{taxonomy}-bgcolor` in EM meta. Pass `null` to clear. image: $ref: "#/components/schemas/ImageAssignmentInput" description: Term image. Accepts an attachment ID, public URL (sideloaded), media-upload object, or `null` to clear. Stored under `{taxonomy}-image` (URL) and `{taxonomy}-image-id` (attachment ID). additionalProperties: false Owner: type: object properties: guest: type: boolean email: type: string format: email name: type: string Permissions: type: object properties: edit: type: boolean delete: type: boolean DeleteEventResponse: type: object required: [deleted, previous] properties: deleted: type: boolean previous: $ref: "#/components/schemas/Event" DeleteLocationResponse: type: object required: [deleted, previous] properties: deleted: type: boolean previous: $ref: "#/components/schemas/Location" DeleteBookingResponse: type: object required: [deleted, previous] properties: deleted: type: boolean previous: $ref: "#/components/schemas/Booking" DeleteTermResponse: type: object required: [deleted, previous] properties: deleted: type: boolean previous: $ref: "#/components/schemas/Term" MediaUploadInput: type: object description: | Polymorphic input — provide ONE of `source_url`, `content_base64`+`filename`, a multipart `file` field, or `id` for an existing attachment. Optional metadata fields apply regardless of upload mode. properties: id: type: integer description: Existing media library attachment ID. Returns its current metadata without re-uploading. source_url: type: string format: uri description: Public URL of a file to sideload into the media library. content_base64: type: string description: Base64-encoded file bytes. Pair with `filename` (required) and `mime_type` (recommended). filename: type: string description: Filename for inline upload. Required when `content_base64` is provided. mime_type: type: string description: MIME type for the inline upload. Optional; sniffed from filename otherwise. title: type: string description: Attachment display title. alt_text: type: string description: Alt text for accessibility (`_wp_attachment_image_alt`). caption: type: string description: Attachment caption (`post_excerpt`). description: type: string description: Long-form attachment description (`post_content`). post_id: type: integer description: Optional parent post ID to attach the upload to. Attachment: type: object properties: id: type: integer example: 12345 url: type: string format: uri example: https://example.com/wp-content/uploads/2026/06/hero.jpg mime_type: type: string example: image/jpeg title: type: string example: Knitting workshop hero alt_text: type: string example: Person knitting with a teal yarn ball width: type: integer nullable: true example: 1920 height: type: integer nullable: true example: 1080 ImageAssignmentInput: description: | Polymorphic image reference used by `featured_image` on events/locations and `image` on terms. Accepts an attachment ID, URL (sideloaded), the full media-upload object shape, or `null` to clear. oneOf: - type: integer description: Existing attachment ID. - type: string description: Public URL — sideloaded into the media library if not already there. - $ref: "#/components/schemas/MediaUploadInput" - type: "null" GenericObject: type: object additionalProperties: true examples: BadRequestError: value: code: em_api_event_invalid message: Event data is invalid. data: status: 400 UnauthorizedError: value: code: rest_not_logged_in message: You are not currently logged in. data: status: 401 ForbiddenError: value: code: em_api_event_forbidden message: You do not have permission to save this event. data: status: 403 NotFoundError: value: code: em_api_event_not_found message: Event not found. data: status: 404 ServerError: value: code: em_api_event_save_failed message: Event could not be saved. data: status: 500 EventExample: value: *event_value EventCollectionExample: value: items: - *event_value pagination: total: 1 total_pages: 1 page: 1 per_page: 20 EventAvailabilityExample: value: event_id: "123" bookings_enabled: true open: true spaces: 24 available_spaces: 18 tickets: - id: 55 name: General Admission description: Standard workshop ticket. price: "49.00" spaces: 24 available_spaces: 18 available: true LocationExample: value: *location_value LocationCollectionExample: value: items: - *location_value pagination: total: 1 total_pages: 1 page: 1 per_page: 20 BookingExample: value: *booking_value BookingCollectionExample: value: items: - *booking_value pagination: total: 1 total_pages: 1 page: 1 per_page: 20 TermExample: value: *term_value TermCollectionExample: value: items: - *term_value pagination: total: 1 total_pages: 1 page: 1 per_page: 20