WP Manifestindependent plugin directory
manifest / integrations / eme-rest-api

Events Made Easy REST API WP Registry grade B. Medium-severity findings · 2 findingsWP RegistryMedium-severity findings · 2 findingsOpen the reportB

REST API endpoints for Events Made Easy WordPress plugin - CRUD operations for events, locations, categories, and recurring events

★ 2stars
13release downloads
v1.10.0latest · 14h ago

Install

Download eme-rest-api.zip From the v1.10.0 release on GitHub, Oct 23, 2026

Upload it under Plugins → Add New Plugin → Upload Plugin, then activate.

Install straight from GitHub with WP-CLI:

wp plugin install https://github.com/gserafini/eme-rest-api/releases/download/v1.10.0/eme-rest-api.zip
No built-in updater. New versions won't appear under Dashboard → Updates. Install new releases yourself, or let Git Updater track the repository.

REST API endpoints for Events Made Easy plugin - CRUD operations for events, locations, categories, and recurring events.

Description

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.

Features

  • ✅ 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

Requirements

  • WordPress 5.0 or higher
  • PHP 7.2 or higher
  • Events Made Easy plugin 2.0+ installed and activated

Installation

Method 1: From GitHub Release

  1. Download the latest eme-rest-api.zip from Releases
  2. In WordPress admin, go to Plugins → Add New → Upload Plugin
  3. Choose the ZIP file and click "Install Now"
  4. Activate the plugin
  5. Ensure Events Made Easy is also installed and activated

Method 2: Manual Installation

  1. Clone this repository or download the source code
  2. Upload the eme-rest-api folder to /wp-content/plugins/
  3. Activate the plugin through the 'Plugins' menu in WordPress
  4. Ensure Events Made Easy is installed and activated

Multisite Installation

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"

API Endpoints

Base URL: https://yoursite.com/wp-json/eme/v1

Events

List Events

GET /eme/v1/eme_events

Query 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-31

Get Single Event

GET /eme/v1/eme_events/{id}

Example:

curl https://yoursite.com/wp-json/eme/v1/eme_events/123

Create Event

POST /eme/v1/eme_events

Required 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: published or draft, default: published)
  • location_id (int)
  • category_ids (array of ints or comma-separated string)
  • rsvp (boolean)
  • seats (int)
  • price (string)
  • currency (string)

Update Event

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 Event

DELETE /eme/v1/eme_events/{id}

Required authentication: Yes

Locations

List Locations

GET /eme/v1/eme_locations

Get Single Location

GET /eme/v1/eme_locations/{id}

Create Location

POST /eme/v1/eme_locations

Request body:

{
  "name": "Conference Center",
  "address": "123 Main St",
  "city": "San Francisco",
  "state": "CA",
  "zip": "94102",
  "country": "USA"
}

Categories

List Categories

GET /eme/v1/eme_categories

Create Category

POST /eme/v1/eme_categories

Request body:

{
  "name": "Workshops",
  "slug": "workshops"
}

Recurring Events

List Recurring Events

GET /eme/v1/eme_recurrences

Returns all recurring event templates (parent events that have recurring instances).

Example:

curl https://yoursite.com/wp-json/eme/v1/eme_recurrences

Response: 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_id field

Create Recurring Event

POST /eme/v1/eme_recurrences

Request 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 Recurrence Instances

GET /eme/v1/eme_recurrences/{id}/instances

Query parameters:

  • start_date (optional): Start date for instances
  • end_date (optional): End date for instances

Authentication

Use WordPress Application Passwords for authentication:

  1. In WordPress admin, go to Users → Profile
  2. Scroll to "Application Passwords"
  3. Create a new application password
  4. Use it with your username in API requests

Example:

curl https://yoursite.com/wp-json/eme/v1/eme_events \
  -u "username:application_password"

Why eme_ Prefix?

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.

Development

File Structure

eme-rest-api/
├── eme-rest-api.php    # Main plugin file
├── readme.txt          # WordPress.org format
└── README.md           # This file

Building

To create a distribution ZIP:

./create-zip.sh

This creates eme-rest-api.zip with only the essential plugin files.

Contributing

Contributions are welcome! Please feel free to:

  • Report issues on GitHub Issues
  • Submit pull requests
  • Suggest new features
  • Improve documentation

Support

Changelog

v1.9.0 - 2025-11-12

  • 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_page from 10 to 0 (unlimited) to match calendar behavior
  • Added show_ongoing=1 by default for multi-day events
  • Removed array parameter which wasn't recognized by EME
  • API now properly returns recurring event instances
  • This matches how EME's calendar frontend queries events

v1.8.2 - 2025-11-12

  • 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

v1.8.1 - 2025-11-12

  • Added passthrough for EME query parameters (recurrences, recurring, month, year, etc.)
  • Added boolean conversion for recurring/recurrences parameters
  • Added debug response headers (X-EME-Query-Args, X-EME-Event-Count)

v1.8.0 - 2025-11-12

  • NEW: Date range query parameters for events endpoint
    • Added start_date and end_date parameters to GET /eme_events
    • Supports filtering events by date range (YYYY-MM-DD format)
    • Date parameters take precedence over scope parameter
  • NEW: List recurring events endpoint
    • Added GET /eme_recurrences to list all recurring event templates
    • Returns parent events that have recurring instances
  • 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

v1.6.2 - 2025-10-30

  • Fixed markdownlint issues in documentation
  • Improved code formatting and documentation
  • Clean repository structure

v1.6.0 - 2025-10-30

  • 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

v1.1.0 - 2025-10-29

  • 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

v1.0.0 - 2025-10-29

  • Initial release
  • Full CRUD operations for events
  • Location management
  • Category management
  • WordPress application password authentication

License

This plugin is licensed under the GNU General Public License v2.0 or later.

Credits

Created by Gabriel Serafini to enable REST API access to Events Made Easy.

Releases

11 releases. Each count is every asset in that release; expand a row for the breakdown.

Tag
Published
Assets
Downloads
v1.10.0 latest
Oct 23, 2026 14h ago
eme-rest-api.zip
1
Oct 22, 2026 17h ago
eme-rest-api.zip
0
Feb 6, 2026 8mo ago
tag only
—
Nov 13, 2025 11mo ago
eme-rest-api.zip
3
Nov 12, 2025 11mo ago
eme-rest-api.zip
0
Nov 12, 2025 11mo ago
eme-rest-api.zip
1
Oct 31, 2025 11mo ago
tag only
—
Oct 30, 2025 11mo ago
eme-rest-api.zip
1
Oct 30, 2025 11mo ago
eme-rest-api.zip
1
Oct 30, 2025 11mo ago
eme-rest-api.zip
1
Oct 30, 2025 11mo ago
eme-rest-api.zip
5
B grade

Security

Events Made Easy REST API 1.9.0 · audited by WP Registry

Medium-severity findings.

1 medium 1 low
Audited release
1.9.0
Findings
2
Worst severity
medium
Content hash
727d1f51e2482a06d01722e4…

Findings

  • medium Event/location write REST gated only by edit_posts and force-bypasses EME caps

    missing_capability

    eme_rest_write_permission returns current_user_can('edit_posts'), so Author-level users can create, update, and delete events, locations, categories, and recurrences through /wp-json/eme/v1/*. eme_rest_create_location calls eme_insert_location($location, 1) explicitly to bypass EME's internal capability check. Sites that restrict EME administration to a higher capability still expose full write via this API to anyone who can edit posts.

    eme-rest-api.php:161-170,645-689

    Recommendation

    Require an EME-appropriate capability (e.g. manage_options or EME's own cap) on write permission_callback, and do not pass force=1 unless that stronger gate already passed.

  • low Unauthenticated read permission_callback always returns true

    missing_permission_callback

    eme_rest_read_permission always returns true, exposing list/get endpoints for events, locations, categories, and recurrences without auth. This may be intentional for public calendars, but single-ID getters do not re-check event_status, so draft/private visibility depends entirely on underlying EME getters.

    eme-rest-api.php:161-165

    Recommendation

    Filter reads by event_status for anonymous users, or require authentication for non-public statuses.

WP Registry hashes the installable build and reports on that exact bytes-for-bytes copy. Embargoed findings are withheld until they are disclosed, so a clean verdict means nothing public is outstanding. WP Manifest does not audit code itself.