REST API endpoints for Events Made Easy plugin - CRUD operations for events, locations, categories, and recurring events.
A WordPress plugin that adds REST API endpoints to the Events Made Easy plugin.
Events Made Easy (EME) uses custom database tables instead of WordPress custom post types, so it doesn't expose events via the WordPress REST API by default. This plugin bridges that gap by providing a clean REST API interface to EME's functionality.
- ✅ Full CRUD operations for events (Create, Read, Update, Delete)
- 📍 Location management
- 🏷️ Category management
- 🔄 Recurring events support
- 🔐 WordPress application password authentication
- 📝 Standard REST API conventions
- 🌐 WordPress Multisite compatible
- WordPress 5.0 or higher
- PHP 7.2 or higher
- Events Made Easy plugin 2.0+ installed and activated
- Download the latest
eme-rest-api.zipfrom Releases - In WordPress admin, go to Plugins → Add New → Upload Plugin
- Choose the ZIP file and click "Install Now"
- Activate the plugin
- Ensure Events Made Easy is also installed and activated
- Clone this repository or download the source code
- Upload the
eme-rest-apifolder to/wp-content/plugins/ - Activate the plugin through the 'Plugins' menu in WordPress
- Ensure Events Made Easy is installed and activated
The plugin works seamlessly with WordPress Multisite:
- Network Activate: Activates for all sites in the network
- Per-Site Activate: Can be activated individually per site
- Table Prefixes: Automatically handles site-specific table prefixes
- REST API: Each site has its own
/wp-json/eme/v1/endpoints - Credentials: Use application passwords from each site's admin
Example multisite usage:
# Site 1
curl https://site1.example.com/wp-json/eme/v1/eme_events \
-u "site1admin:site1_app_password"
# Site 2
curl https://site2.example.com/wp-json/eme/v1/eme_events \
-u "site2admin:site2_app_password"Base URL: https://yoursite.com/wp-json/eme/v1
GET /eme/v1/eme_eventsQuery parameters:
per_page(int): Events per page (default: 10)page(int): Page number (default: 1)scope(string): Event scope -future,past,today,month, etc. (default:future)start_date(string): Filter events starting from this date (YYYY-MM-DD)end_date(string): Filter events ending before this date (YYYY-MM-DD)
Note: If start_date or end_date are provided, they take precedence over scope.
Examples:
# Get future events
curl https://yoursite.com/wp-json/eme/v1/eme_events?per_page=5&scope=future
# Get events in a specific date range
curl https://yoursite.com/wp-json/eme/v1/eme_events?start_date=2025-11-01&end_date=2025-11-30
# Get all events from a start date onwards
curl https://yoursite.com/wp-json/eme/v1/eme_events?start_date=2025-11-01
# Get all events before an end date
curl https://yoursite.com/wp-json/eme/v1/eme_events?end_date=2025-12-31GET /eme/v1/eme_events/{id}Example:
curl https://yoursite.com/wp-json/eme/v1/eme_events/123POST /eme/v1/eme_eventsRequired authentication: Yes (application password or OAuth)
Request body:
{
"title": "Annual Meeting",
"description": "Everyone is welcome to attend",
"start_date": "2025-11-08 13:00:00",
"end_date": "2025-11-08 16:00:00",
"status": "published",
"location_id": 5,
"category_ids": [1, 3],
"rsvp": true,
"seats": 100,
"price": "25.00",
"currency": "USD"
}Required fields:
title(string)start_date(datetime:YYYY-MM-DD HH:MM:SS)
Optional fields:
description(string)end_date(datetime, defaults to start_date)status(string:publishedordraft, default:published)location_id(int)category_ids(array of ints or comma-separated string)rsvp(boolean)seats(int)price(string)currency(string)
POST /eme/v1/eme_events/{id}
PUT /eme/v1/eme_events/{id}
PATCH /eme/v1/eme_events/{id}Required authentication: Yes
Request body: Same as create, all fields optional
Example:
curl -X POST https://yoursite.com/wp-json/eme/v1/eme_events/123 \
-u "username:application_password" \
-H "Content-Type: application/json" \
-d '{"title": "Updated Event Title", "seats": 150}'DELETE /eme/v1/eme_events/{id}Required authentication: Yes
GET /eme/v1/eme_locationsGET /eme/v1/eme_locations/{id}POST /eme/v1/eme_locationsRequest body:
{
"name": "Conference Center",
"address": "123 Main St",
"city": "San Francisco",
"state": "CA",
"zip": "94102",
"country": "USA"
}GET /eme/v1/eme_categoriesPOST /eme/v1/eme_categoriesRequest body:
{
"name": "Workshops",
"slug": "workshops"
}GET /eme/v1/eme_recurrencesReturns all recurring event templates (parent events that have recurring instances).
Example:
curl https://yoursite.com/wp-json/eme/v1/eme_recurrencesResponse: Array of event objects that are recurring templates. Each event will have:
recurrence_id:0(these are the parent templates)- Child events reference these via their
recurrence_idfield
POST /eme/v1/eme_recurrencesRequest body for weekly recurrence:
{
"title": "Weekly Team Meeting",
"frequency": "weekly",
"days_of_week": [1, 3, 5],
"start_date": "2025-11-01 09:00:00",
"end_date": "2025-12-31 09:00:00",
"duration": 3600,
"location_id": 5
}Request body for monthly recurrence:
{
"title": "Monthly Board Meeting",
"frequency": "monthly",
"day_of_month": 15,
"start_date": "2025-11-01 14:00:00",
"end_date": "2026-11-01 14:00:00",
"duration": 7200
}GET /eme/v1/eme_recurrences/{id}/instancesQuery parameters:
start_date(optional): Start date for instancesend_date(optional): End date for instances
Use WordPress Application Passwords for authentication:
- In WordPress admin, go to Users → Profile
- Scroll to "Application Passwords"
- Create a new application password
- Use it with your username in API requests
Example:
curl https://yoursite.com/wp-json/eme/v1/eme_events \
-u "username:application_password"Endpoints use the eme_ prefix to avoid conflicts with Events Made Easy's custom post types. This ensures the REST API routes take precedence over WordPress's default post type routing.
eme-rest-api/
├── eme-rest-api.php # Main plugin file
├── readme.txt # WordPress.org format
└── README.md # This file
To create a distribution ZIP:
./create-zip.shThis creates eme-rest-api.zip with only the essential plugin files.
Contributions are welcome! Please feel free to:
- Report issues on GitHub Issues
- Submit pull requests
- Suggest new features
- Improve documentation
- Plugin Issues: GitHub Issues
- Events Made Easy: EME GitHub
- MAJOR FIX: Complete rewrite of
eme_get_events()call to use positional parameters - API now returns ALL events matching criteria (like calendar frontend does)
- Fixed default
per_pagefrom 10 to 0 (unlimited) to match calendar behavior - Added
show_ongoing=1by default for multi-day events - Removed
arrayparameter which wasn't recognized by EME - API now properly returns recurring event instances
- This matches how EME's calendar frontend queries events
- CRITICAL FIX: Date range separator changed from comma to double-dash
- Fixed date range queries to use EME's expected format (
YYYY-MM-DD--YYYY-MM-DD) - This fix resolves the issue where API was only returning 1 event for date ranges
- Added passthrough for EME query parameters (
recurrences,recurring,month,year, etc.) - Added boolean conversion for
recurring/recurrencesparameters - Added debug response headers (
X-EME-Query-Args,X-EME-Event-Count)
- NEW: Date range query parameters for events endpoint
- Added
start_dateandend_dateparameters toGET /eme_events - Supports filtering events by date range (YYYY-MM-DD format)
- Date parameters take precedence over
scopeparameter
- Added
- NEW: List recurring events endpoint
- Added
GET /eme_recurrencesto list all recurring event templates - Returns parent events that have recurring instances
- Added
- FIXED: Events API now properly returns all events including recurring instances
- Previously only returned limited results due to parameter handling
- Now correctly passes date range to EME's query functions
- Fixed markdownlint issues in documentation
- Improved code formatting and documentation
- Clean repository structure
- BREAKING: Renamed all endpoints to use
eme_prefix to avoid conflicts/events→/eme_events/locations→/eme_locations/categories→/eme_categories/recurrences→/eme_recurrences
- Fixed WordPress routing conflicts with EME custom post types
- Switched to using EME's built-in functions for better reliability
- NEW: Recurring events support
- Create weekly, monthly, or specific-date recurring events
- Get recurrence instances
- Update and delete recurrences
- Enhanced event formatting with proper URL generation
- Added multisite compatibility
- Improved error handling
- Initial release
- Full CRUD operations for events
- Location management
- Category management
- WordPress application password authentication
This plugin is licensed under the GNU General Public License v2.0 or later.
Created by Gabriel Serafini to enable REST API access to Events Made Easy.