Docs Evenzo – Events Manager for WooCommerce

REST API

REST API#

Access event data through the WordPress REST API. Build custom integrations, mobile apps, or external displays.

Overview#

The API provides endpoints for:

  • Events (create, read, update, delete)
  • Venues (create, read, update, delete)
  • Organizers (create, read, update, delete)
  • Attendees (read, update, lookup by ticket code)
  • Check-in (check in, check out, validate, stats, recent)
  • Calendar data (month, range, upcoming, categories)
  • Webhooks (see the Webhooks page)

There is no speakers endpoint.

Base URL#

All endpoints use the base:

https://yoursite.com/wp-json/emwc/v1/

The API can be switched off under Events > Settings > Advanced > REST API (option emwc_enable_rest_api). When it is off, every emwc/v1 request returns emwc_api_disabled with status 403.

Authentication#

Public endpoints#

These endpoints work without authentication:

  • GET events, venues, organizers (published items only)
  • GET calendar/*
  • GET webhooks/topics

Protected endpoints#

OperationCapability
POST events, venues, organizersedit_posts
PUT events, venues, organizersedit_post on that item
DELETE events, venues, organizersdelete_post on that item
All attendees and checkin routesmanage_woocommerce
All webhooks routes except topicsmanage_options

Authentication methods#

Application Passwords (recommended)

  1. Go to Users > Profile
  2. Scroll to Application Passwords
  3. Create a new password
  4. Use it with HTTP Basic Auth
curl -u username:application_password https://yoursite.com/wp-json/emwc/v1/events

Cookie authentication For logged-in requests from JavaScript on your site. Send the X-WP-Nonce header.

Pagination#

List endpoints return X-WP-Total and X-WP-TotalPages headers and a Link header with prev and next URLs.

Events endpoints#

List events#

GET /wp-json/emwc/v1/events

Only published events are returned.

Parameters

ParameterTypeDescription
pageintPage number (default: 1)
per_pageintResults per page (default: 10, max: 100)
searchstringSearch term
orderbystringdate (default), title, modified, id, meta_value
orderstringASC or DESC (default)
statusstringEvent status: scheduled, cancelled, postponed, sold-out
categorystringCategory ID or slug
venueintVenue ID
organizerintOrganizer ID
start_afterstringEvents starting on or after this date
start_beforestringEvents starting on or before this date
upcomingboolOnly events starting today or later
featuredboolOnly featured events
includestringComma-separated IDs to include
excludestringComma-separated IDs to exclude
_embedboolAdd venue and organizer objects to each event

Example

curl "https://yoursite.com/wp-json/emwc/v1/events?per_page=5&status=scheduled&upcoming=1"

Response

[
  {
    "id": 123,
    "title": "Tech Conference 2025",
    "slug": "tech-conference-2025",
    "status": "publish",
    "content": "Annual technology conference...",
    "excerpt": "",
    "permalink": "https://yoursite.com/events/tech-conference-2025/",
    "date_created": "2025-01-10T08:00:00",
    "date_modified": "2025-01-12T09:30:00",
    "featured_image": { "id": 55, "url": "...", "thumbnail": "...", "alt": "" },
    "start_date": "2025-03-15",
    "start_time": "09:00",
    "end_date": "2025-03-15",
    "end_time": "17:00",
    "start_datetime": "2025-03-15T09:00:00",
    "end_datetime": "2025-03-15T17:00:00",
    "timezone": "America/New_York",
    "all_day": false,
    "venue_id": 45,
    "organizer_id": 12,
    "capacity": 500,
    "event_status": "scheduled",
    "event_type": "in-person",
    "virtual_url": "",
    "featured": false,
    "categories": [3],
    "_links": { "self": [...], "collection": [...] }
  }
]

status is the WordPress post status. event_status is the event status shown in the admin.

Get single event#

GET /wp-json/emwc/v1/events/{id}

Unpublished events need read_post permission.

Create event#

POST /wp-json/emwc/v1/events

Body fields

FieldTypeDescription
titlestringRequired
contentstringDescription (HTML allowed)
excerptstringShort description
statusstringPost status: publish (default), draft, pending, private
start_date, end_datestringYYYY-MM-DD
start_time, end_timestringHH:MM
timezonestringTimezone name
all_dayboolAll-day event
venue_idintVenue ID
organizer_idintOrganizer ID
capacityintMaximum attendees
event_statusstringscheduled, cancelled, postponed, sold-out
event_typestringin-person, virtual, hybrid
virtual_urlstringVirtual event URL
featuredboolFeatured event
categoriesint[]Category term IDs
{
  "title": "New Workshop",
  "content": "Workshop description here",
  "start_date": "2025-04-01",
  "start_time": "14:00",
  "end_date": "2025-04-01",
  "end_time": "16:00",
  "event_status": "scheduled",
  "event_type": "in-person",
  "venue_id": 45,
  "organizer_id": 12,
  "capacity": 30
}

Returns status 201 with a Location header.

Update event#

PUT /wp-json/emwc/v1/events/{id}

Accepts the same fields as create. Only fields you send are changed.

Delete event#

DELETE /wp-json/emwc/v1/events/{id}

Moves the event to trash. Add force=true to delete permanently. Returns { "deleted": true, "previous": { ... } }.

Venues endpoints#

GET    /wp-json/emwc/v1/venues
GET    /wp-json/emwc/v1/venues/{id}
POST   /wp-json/emwc/v1/venues
PUT    /wp-json/emwc/v1/venues/{id}
DELETE /wp-json/emwc/v1/venues/{id}

List parameters: page, per_page, search, orderby (title default, date, modified, id), order (ASC default), city, country.

Body fields: name (required on create), address, city, state, country, postal, capacity, phone, email, website.

Response fields: the body fields plus id, date_created, date_modified, event_count, _links.

{
  "name": "Downtown Hall",
  "address": "123 Main St",
  "city": "New York",
  "state": "NY",
  "postal": "10001",
  "country": "US",
  "capacity": 200
}

Organizers endpoints#

GET    /wp-json/emwc/v1/organizers
GET    /wp-json/emwc/v1/organizers/{id}
POST   /wp-json/emwc/v1/organizers
PUT    /wp-json/emwc/v1/organizers/{id}
DELETE /wp-json/emwc/v1/organizers/{id}

List parameters: page, per_page, search, orderby (title default, date, modified, id), order (ASC default).

Body fields: name (required on create), phone, email, website, facebook, twitter, linkedin.

Response fields: the body fields plus id, date_created, date_modified, event_count, _links.

Attendees endpoints#

All attendee routes require manage_woocommerce.

List attendees#

GET /wp-json/emwc/v1/attendees
ParameterTypeDescription
pageintPage number (default: 1)
per_pageintResults per page (default: 10, max: 100)
searchstringMatches first name, last name, email, or ticket code
orderbystringcreated_at (default), first_name, last_name, email, status
orderstringASC or DESC (default)
eventintFilter by event ID
order_idintFilter by WooCommerce order ID
statusstringactive, cancelled, checked_in, checked_out

Response

[
  {
    "id": 456,
    "event_id": 123,
    "event_name": "Tech Conference 2025",
    "order_id": 789,
    "order_number": "789",
    "user_id": 7,
    "first_name": "John",
    "last_name": "Doe",
    "email": "john@example.com",
    "phone": "",
    "ticket_code": "EMWC-ABC123DEF",
    "status": "active",
    "checked_in_at": null,
    "checked_out_at": null,
    "custom_fields": {},
    "date_created": "2025-01-15T10:30:00",
    "date_modified": "2025-01-15T10:30:00",
    "qr_code_url": "https://...",
    "_links": { "self": [...], "collection": [...] }
  }
]

Get single attendee#

GET /wp-json/emwc/v1/attendees/{id}
GET /wp-json/emwc/v1/attendees/code/{ticket_code}

Update attendee#

PUT /wp-json/emwc/v1/attendees/{id}

Fields: first_name, last_name, email, phone, status (active, cancelled, checked_in, checked_out). Fires emwc_rest_attendee_updated.

Check-in endpoints#

All check-in routes require manage_woocommerce.

Check in#

POST /wp-json/emwc/v1/checkin
FieldTypeDescription
ticket_codestringRequired
event_idintOptional. Rejects the ticket if it belongs to another event

Response

{
  "success": true,
  "message": "Successfully checked in!",
  "attendee": {
    "id": 456,
    "name": "John Doe",
    "email": "john@example.com",
    "ticket_code": "EMWC-ABC123DEF",
    "status": "checked_in",
    "event_id": 123,
    "event_name": "Tech Conference 2025"
  },
  "checked_in_at": "2025-03-15 09:15:00"
}

A ticket that is already checked in returns success: true with already_in: true.

Errors: emwc_rest_invalid_ticket (404), emwc_rest_wrong_event (400), emwc_rest_cancelled_ticket (400), emwc_rest_checkin_failed (500).

Check out#

POST /wp-json/emwc/v1/checkin/checkout

Body: ticket_code. The attendee must be checked in, otherwise emwc_rest_not_checked_in (400) is returned.

Validate a ticket#

POST /wp-json/emwc/v1/checkin/validate

Body: ticket_code, optional event_id. Does not change the ticket. Always returns status 200 with valid (bool), message, and attendee and status when the ticket exists.

Check-in stats#

GET /wp-json/emwc/v1/checkin/stats/{event_id}

Returns event_id, event_name, total, pending, checked_in, checked_out, cancelled, percentage.

Recent check-ins#

GET /wp-json/emwc/v1/checkin/recent/{event_id}?limit=10

limit is capped at 50. Returns event_id, event_name, and checkins (id, name, ticket_code, status, checked_in_at, checked_out_at).

Calendar endpoints#

All calendar routes are public and return published events only.

Month#

GET /wp-json/emwc/v1/calendar/month
ParameterTypeDescription
yearintDefault: current year
monthint1 to 12 (default: current month)
categorystringCategory ID or slug

Returns year, month, month_name, start_date, end_date, total_events, events, and events_by_date (events keyed by start date).

Range#

GET /wp-json/emwc/v1/calendar/range?start=2025-03-01&end=2025-03-31

start and end are required (YYYY-MM-DD). The range cannot exceed 365 days. Optional category.

Upcoming#

GET /wp-json/emwc/v1/calendar/upcoming?limit=5

limit is 1 to 50 (default: 5). Optional category.

Categories#

GET /wp-json/emwc/v1/calendar/categories?hide_empty=true

Returns total and categories (id, name, slug, description, count, color).

Calendar event fields#

Each event in a calendar response has: id, title, slug, url, start_date, start_time, end_date, end_time, all_day, start, end (ISO date-time strings), venue (name), venue_id, categories (id, name, slug, color), color, thumbnail, event_status, event_type, featured.

Error handling#

Error response format#

{
  "code": "emwc_rest_forbidden",
  "message": "Sorry, you are not allowed to manage attendees.",
  "data": {
    "status": 403
  }
}

Common error codes#

CodeStatusDescription
emwc_api_disabled403REST API switched off in settings
emwc_rest_forbidden401 or 403Missing or insufficient permission
emwc_rest_event_invalid_id404Event not found
emwc_rest_venue_invalid_id404Venue not found
emwc_rest_organizer_invalid_id404Organizer not found
emwc_rest_attendee_invalid_id404Attendee not found
emwc_rest_attendee_invalid_code404Ticket code not found
emwc_rest_cannot_delete500Delete failed
rest_invalid_param400Parameter failed validation

Rate limiting#

The API does not impose rate limits. Use a caching plugin or CDN for high-traffic APIs.

Examples#

JavaScript fetch#

fetch("https://yoursite.com/wp-json/emwc/v1/events?upcoming=1")
  .then((response) => response.json())
  .then((events) => console.log(events));

PHP with wp_remote_get#

$response = wp_remote_get( 'https://yoursite.com/wp-json/emwc/v1/events' );
$events   = json_decode( wp_remote_retrieve_body( $response ) );

cURL#

curl -X POST \
  -H "Content-Type: application/json" \
  -u admin:application_password \
  -d '{"ticket_code":"EMWC-ABC123DEF"}' \
  https://yoursite.com/wp-json/emwc/v1/checkin

Extending the API#

Custom endpoints#

add_action( 'rest_api_init', function() {
    register_rest_route( 'emwc/v1', '/custom', array(
        'methods'             => 'GET',
        'callback'            => 'my_custom_endpoint',
        'permission_callback' => '__return_true',
    ) );
} );

Modifying responses#

Each resource has a prepare filter:

add_filter( 'emwc_rest_prepare_event', function( $data, $post, $request ) {
    $data['custom_field'] = get_post_meta( $post->ID, 'custom_field', true );
    return $data;
}, 10, 3 );
FilterArguments
emwc_rest_prepare_event$data, $post, $request
emwc_rest_prepare_venue$data, $post, $request
emwc_rest_prepare_organizer$data, $post, $request
emwc_rest_prepare_attendee$data, $attendee (array), $request

Actions#

ActionArguments
emwc_rest_event_created, emwc_rest_event_updated$post_id, $request
emwc_rest_event_deleted$post_id, $force
emwc_rest_venue_created, emwc_rest_venue_updated$post_id, $request
emwc_rest_venue_deleted$post_id, $force
emwc_rest_organizer_created, emwc_rest_organizer_updated$post_id, $request
emwc_rest_organizer_deleted$post_id, $force
emwc_rest_attendee_updated$attendee_id, $request
emwc_attendee_checked_in, emwc_attendee_checked_out$attendee_id, $attendee