Installation
https://eventespresso.com/product/espresso-json-api/
The Event Espresso JSON API add-on installs like any other WordPress plugin (via the WordPress admin or using FTP).
Once installed, just configure the settings, to your needs, in the WP Admin > Event Espresso > API Settings page of your Event Espresso powered WordPress website.
Testing the JSON API
To make sure the JSON API is working properly on your website, you add this to the end of your Event Espresso powered website’s URL:
/espresso-api/v1/events/public.pretty_json
Example: yoursite.com/espresso-api/v1/events/public.pretty_json
Actual example from our testdrive website: https://eventespresso.com/testdrive/espresso-api/v1/events/public.pretty_json
If everything is configured properly, you will see something like this:
API Codex
The Event Espresso JSON API gives developers a complete API platform for directly accessing data event and attendee data securely and efficiently from outside your web server. All a developer needs to know about is the API Endpoint URL for your site. Example: https://eventespresso.com/testdrive/espresso-api/v1/events/public.pretty_json
Authentication
Private Information
To make most requests to the API, you will need to send a session key with each request in the URL. Eg: mysite.com/espresso-api/v1/events/qwer1234 (where “qwer1234” is the session key).
To acquire a session key, send an HTTP POST/GET to
{wordpress-site}/espresso-api/v1/authenticate
with GET or POST parameters: “username” and “password” (which are a wordpress user’s username and password.)
Eg: GET mysite.com/espresso-api/v1/authenticate?username=admin&password=3v3nt (NOTE: using GET on this endpoint is not recommended for production, as it is less secure than sending a POST)
POST mysite.com/espresso-api/v1/authenticate
with body:
username:admin password:3v3nt
On success, the response will look like:
{"status":"OK","status_code":200,"body":{"session_key":"fwseljoxy5"}}
On failure, the response will look like:
{"status":"Bad username and password combination.","status_code":401}
Public Information
Event Espresso site admins can allow for some information to be publicly available, thus not requiring authentication to access it. To enable this feature, they must select to “Allow Public API Access” on the Event Espresso API Settings page.
To query for public information, there is no need to authenticate and retrieve a session key. Instead, simply use the string ‘public’ in place of a session key in all requests. Eg, mysite.com/espresso-api/v1/events/public. Please see the section titled “Permissions” for information on what information is publicly available when this feature is enabled.
Response/Request Formats (xml, json,pretty_json)
this API supports both JSON (default) and XML formats. To get a response back in XML, simply append “.xml” to any of the session key (eg, “mysite.com/espresso-api/v1/events/{session_key}.xml?id__lt=10” or “mysite.com/espresso-api/v1/events/14/{session_key}.xml?). If you would like to have your JSON returned in a more readable, but less efficient, format, simply set the format to ‘pretty_json’ (eg, “mystei.com/espresso-api/v1/events/{session_key}.pretty_json?id__in=1,23,342)
Request Methods (GET, POST, PUT, DELETE)
According to RESTful principles, the HTTP request method sent to an endpoint dictates functionality in this API. Eg: sending the request method of DELETE on a request will be interpreted very differently by the API server than the same request using the PUT request method. In the following documentation, each endpoint is preceded by the HTTP request method that invokes that functionality. (Eg the title “GET /events” explains the functionality of sending a request to “/events” using the GET request method).
If you are unable to send PUT or DELETE request methods, we have provided a workaround: in the body of your request, provide a parameter called ‘request_method’ and set its value to the desired request method. Eg, if you want to send a PUT request but are unable, send a POST request with the request parameters ‘request_method’:’PUT’ (and the usual ‘body’ parameter with the json or xml to indicate what you want to update). Or if you want to send a DELETE request to /events/{id}/{sessionId}, send the following GET request /events/{id}/{sessionid}?request_method=DELETE.
GETting with Query Parameters
On all GET requests (eg, an HTTP GET request to mysite.com/espresso-api/v1/events,) you may add GET querystring variables to filter your results, eg mysite.com/espresso-api/v1/events?Datetime.event_start2012-04-23%2000:00:00.
But, what if you want all events before April 23rd 2012? you’d like to use mysite.com/espresso-api/v1/events?Datetime.event_start<2012-04-23%2000:00:00, but that’s invalid HTTP querystring syntax. If you want to alter a query like that simply append ‘__lt’ to the querystring parameter and it will be interpreted as < (or “less than”). ie mysitecom/espresso-api/v1/events?Datetime.event_start__lt=2012-04-23%2000:00:00. The following operators are available:
MySQL Operator | String to Append to Query Parameter | Example |
---|---|---|
< | __lt | eg: mysite.com/espresso-api/v1/events?Datetime.event_start__lt=2012-04-23%2012:23:56 |
<= | __lte | eg: mysite.com/espresso-api/v1/events?Datetime.event_start__lte=2012-04-23%2012:23:56 |
> | __gt | eg: mysite.com/espresso-api/v1/events?Datetime.event_start__gte=2012-04-23%2012:23:56 |
>= | __gte | eg: mysite.com/espresso-api/v1/events?Datetime.event_start__gt=2012-04-23%2012:23:56 |
LIKE | __like | eg: mystie.com/esresso-api/v1/attendees?fname__like=%25Tim%25 (note that ‘%’ urlencoded is %25) |
IN | __in | eg: mysite.com/espresso-api/v1/registrations__in=234,432,345 |
You may also query based on most related models, as long as they are part of the response of the endpoint you’re currenlty querying.
For example, Price is a related model of Event, and is always included on any query to Events. So if you want to find all events with a price of 12.00, you could do a query like mysite.com/espresso-api/v1/events/{session_key}?Price.amount=12.00.
Further Examples:
Example Request | Description | generated SQL for WHERE statement |
---|---|---|
GET mysite.com/espresso-api/v1/events/{session_key}?name__like=%25party%25&description__like=%25all%20fun%25 | Get all events where the name has a substring of ‘party’, and where the event description has the substring ‘all fun’ | WHERE event_name LIKE ‘%party%’ AND event_desc LIKE ‘%all fun%’ |
GET mysite.com/espresso-api/v1/events/{session_key}?/events/{session_key}?Datetime.event_start__lt=2012-02-06%2012:23:56 | get all events which start before february 6th 2012 | WHERE Datetime.event_start < ‘2012-02-06%2012:23:56’ |
GET mysite.com/espresso-api/v1/registrations/{session_key}?Event.id__lt=5 | get all registrations whose associated Event.id is less than 5 | WHERE wp_events_detail < 5 |
POSTing (creating) with Temp Ids
When POSTing info to a resource to create a new one (eg, posting registration info to espresso-api/v1/registrations/{sessionId})
your soon-to-be-created resource will not yet have an ID. Insetad, you must provide a temporary ID. Temporary IDs are strings
starting with “temp-” and following by any unique string (eg, “temp-my-new-reg”, “temp-123”, “temp-a”, etc).
Why use Temporary Ids (instead of just ignoring the ID field)?
Temporary Ids are handy when creating multiple related resources, and thus allow you to refer to the soon-to-be-created resources.
Eg, creating 2 registrations on a single new transaction. Each registration would have their own unique Temp Id, (eg
“temp-reg1” AND “temp-reg2″”) and each would have their nested Transaction’s id set to a single
Temp Id (eg “temp-transaction-for-both-regs”). Example request:
{ "Registrations":[ { "id":"temp-reg1", "status":"not_approved", "date_of_registration":"2012-12-10 16:12:31", "final_price":10, "code":"1-50c67a6f172e1", "url_link":null, "is_primary":true, "is_group_registration":true, "is_going":true, "is_checked_in":false, "Transaction":{ "id":"temp-transaction-for-both-regs" } }, { "id":"temp-reg2", "status":"not_approved", "date_of_registration":"2012-12-10 16:12:31", "final_price":10, "code":"1-50c67a6f172e1", "url_link":null, "is_primary":false, "is_group_registration":false, "is_going":true, "is_checked_in":false, "Transaction":{ "id":"temp-transaction-for-both-regs" } } ] }
Query Limits
By default, all queries will return a maximum of 50 primary items (‘primary items’ meaning the item requested, not related items. So on a request to mysite.com/espresso-api/v1/events/public that would be ‘events’, not the
related datetimes, venues, or categories, etc.). If you wish to change this limit, provide another query parameter called ‘limit’. Eg, mysite.com/espresso-api/v1/events/{sessionkey}?limit=75 or mysite.com/espresso-api/v1/attendees/{sessionkey}?id__gt=50&limit=50 (the will
request the first 75 items, the second will get the first 50 items with an ID higher than 50, which might be a convenient way of doing pagination).
The query limit parameter used on regular endpoints for GETs is different from the query limit on cached results. Please see the section on ‘caching’. There is currently no ‘offset’ parameter for query limits on regular endpoints (ie, mysite.com/espresso-api/v1/events/{sessionkey}?limit=150,50 will NOT work).
This feature is planned in future versions of the API.
Endpoints
The API data structure is independent of the Event Espresso MySQL database structure (ie, the data is organized differently. Eg, in the Event Espresso 3.1 database, there is no concept of ‘registration’ or ‘transaction’, these are simply part of an attendee record.) Here is an image which shows how the data is organized and generally which resources contain what information.
Events
Currently, you may get events and filter them
GET /events
gets all events, and their related datetimes, prices, promocodes, categories, and venues. For efficiency, the related registrations are not returned on this endpoint. For those, see GET /events/{id}registrations. Also, by default only active events are returned (ie, mysite.com/espresso-api/v1/events/{session_key} will return the exact same results as mysite.com/espresso-api/v1/events/{session_key}?status_in=active,draft,secondary/waitlist), but you can of course override this by supplying a different value for the “status” parameter.
The following will all be part of the response, and may be used in querying
id: the event’s DB id, eg 12 name: name of the event, eg “mike party” description: description of the event, eg “all you can ease pizza!” Datetimes: list of tuples like GET /datetimes Venues: list of tuples of the venues, GET /venues metadata: list of tuples,eg “metadata”:{“id”:23,”{meta_key}”,”{meta_value}”, “date_added”:”2012-03-23 23:33:44”} status: string. one of 'active', 'inactive', 'pending', 'draft', 'secondary/waitlist', 'ongoing', 'denied', 'deleted' limit: integer group_registrations_allowed: boolean group_registrants_max: integer active: boolean member_only: boolean Categories: lsit of tuple like /categories Promocodes: list of tuples like /promocodes virtual_url: string virtual_phone: string phone: string
Example Request (gets all events submitted before march 24th 2012 by user with id 1)
mysite.com/espresso-api/v1/events/{session_key}?submitted__lte=2012-03-24%2012:23:56&user_id=1
Example Response
{ "status":"OK", "status_code":200, "body":{ "Events":[ { "id":"1", "name":"Jump Til You Drop", "description":"This is a test. <!--more-->\r\n\r\n[ESPRESSO_VENUE]", "status":"active", "limit":"500", "group_registrations_allowed":true, "group_registrations_max":"10", "active":true, "member_only":false, "virtual_url":"", "call_in_number":"", "phone":"", "metadata":{ "default_payment_status":"", "venue_id":"0", "additional_attendee_reg_info":"3", "add_attendee_question_groups":{ "1":"1", "11":"11" }, "date_submitted":"June 18, 2012", "event_hashtag":"", "event_format":"", "event_livestreamed":"", "":"" }, "Datetimes":[ { "id":"120", "is_primary":true, "event_start":"2012-10-31 08:00:00", "event_end":"2012-10-31 17:00:00", "registration_start":"2012-07-01 00:01:00", "registration_end":"2012-10-31 23:59:00", "limit":"0", "tickets_left":"500" } ], "Venues":[ ], "Categories":[ { "id":"1", "name":"Test category", "identifier":"test-cat", "description":"My category content", "user":"1" } ], "Promocodes":[ ], "Prices":[ { "id":"155.0", "name":"Admission + T-shirt", "amount":"2.00", "description":null, "limit":"500", "remaining":999999, "start_date":null, "end_date":null, "Pricetype":{ "id":1, "name":"Base Price", "is_member":false, "is_discount":false, "is_tax":false, "is_percent":false, "is_global":true, "order":0 } }, { "id":"155.2", "name":"Members Admission", "amount":"2.00", "description":null, "limit":"500", "remaining":99999, "start_date":null, "end_date":null, "Pricetype":{ "id":4, "name":"Member Price", "is_member":true, "is_discount":false, "is_tax":false, "is_percent":false, "is_global":true, "order":0 } }, { "id":"154.0", "name":"General Admission", "amount":"0.01", "description":null, "limit":"500", "remaining":999999, "start_date":null, "end_date":null, "Pricetype":{ "id":1, "name":"Base Price", "is_member":false, "is_discount":false, "is_tax":false, "is_percent":false, "is_global":true, "order":0 } }, { "id":"154.2", "name":"Members Admission", "amount":"0.01", "description":null, "limit":"500", "remaining":99999, "start_date":null, "end_date":null, "Pricetype":{ "id":4, "name":"Member Price", "is_member":true, "is_discount":false, "is_tax":false, "is_percent":false, "is_global":true, "order":0 } } ] } ] } }
GET /events/{id}
retrieves a single event and its related , where {id} is the id of the event you want to retrieve. Accepts no querystring variables.
Example Request:
mysite.com/espresso-api/v1/events/123/{session_key}
Example Response:
{ "status":"OK", "status_code":200, "body":{ "Event":{ "id":"1", "name":"Jump Til You Drop", "description":"This is a test. <!--more-->\r\n\r\n[ESPRESSO_VENUE]", "status":"active", "limit":"500", "group_registrations_allowed":true, "group_registrations_max":"10", "active":true, "member_only":false, "virtual_url":"", "call_in_number":"", "phone":"", "metadata":{ "default_payment_status":"", "venue_id":"0", "additional_attendee_reg_info":"3", "add_attendee_question_groups":{ "1":"1", "11":"11" }, "date_submitted":"June 18, 2012", "event_hashtag":"", "event_format":"", "event_livestreamed":"", "":"" }, "Datetimes":[ { "id":"120", "is_primary":true, "event_start":"2012-10-31 08:00:00", "event_end":"2012-10-31 17:00:00", "registration_start":"2012-07-01 00:01:00", "registration_end":"2012-10-31 23:59:00", "limit":"0", "tickets_left":"500" } ], "Venues":[ ], "Categories":[ { "id":"1", "name":"Test category", "identifier":"test-cat", "description":"My category content", "user":"1" } ], "Promocodes":[ ], "Prices":[ { "id":"155.0", "name":"Admission + T-shirt", "amount":"2.00", "description":null, "limit":"500", "remaining":999999, "start_date":null, "end_date":null, "Pricetype":{ "id":1, "name":"Base Price", "is_member":false, "is_discount":false, "is_tax":false, "is_percent":false, "is_global":true, "order":0 } }, { "id":"155.2", "name":"Members Admission", "amount":"2.00", "description":null, "limit":"500", "remaining":99999, "start_date":null, "end_date":null, "Pricetype":{ "id":4, "name":"Member Price", "is_member":true, "is_discount":false, "is_tax":false, "is_percent":false, "is_global":true, "order":0 } }, { "id":"154.0", "name":"General Admission", "amount":"0.01", "description":null, "limit":"500", "remaining":999999, "start_date":null, "end_date":null, "Pricetype":{ "id":1, "name":"Base Price", "is_member":false, "is_discount":false, "is_tax":false, "is_percent":false, "is_global":true, "order":0 } }, { "id":"154.2", "name":"Members Admission", "amount":"0.01", "description":null, "limit":"500", "remaining":99999, "start_date":null, "end_date":null, "Pricetype":{ "id":4, "name":"Member Price", "is_member":true, "is_discount":false, "is_tax":false, "is_percent":false, "is_global":true, "order":0 } } ] } } }
GET /events/{id}/registrations
returns all registrations for event with {id}. Output is identical to GET /registrations?Event.id={id}
Registrations
GET /registrations
gets all registrations, and their related attendee, transaction, event, price (and pricetype), and datetime.
id id of registration (float NOT int) Event: tuple like topleve GET /event Attendee: tuple like toplevel GET /attendees Transaction: tuple like topleve GET transaction Datetime: tuple like toplevel GET /datetimes Price: tuple like GET /prices status: ‘approved’,’cancelled’,’not_approved’,’pending’ date_of_registration: datetime like ‘2012-03-23 23:12:53” final_price: string like “20.34” code: string url_link: string is_primary: boolean is_group_registration: string true or false is_going: boolean is_checked_in: boolean
Example Request:
mysite.com/espresso-api/v1/registrations/{session_key}?Attendee.firstname__like=%25Smith%25&is_checked_in=1 //note that '%' urlencoded is %25
Example Response
{ "status":"OK", "status_code":200, "body":{ "Registrations":[ { "id":"9273", "status":"approved", "date_of_registration":"2012-10-22 21:14:04", "final_price":"0.01", "code":"1-50860b7c7d415", "url_link":null, "is_primary":true, "is_group_registration":false, "is_going":true, "is_checked_in":false, "Event":{ "id":"1", "name":"Jump Til You Drop", "description":"This is a test. <!--more-->\r\n\r\n[ESPRESSO_VENUE]", "status":"active", "limit":"500", "group_registrations_allowed":true, "group_registrations_max":"10", "active":true, "member_only":false, "virtual_url":"", "call_in_number":"", "phone":"", "metadata":{ "default_payment_status":"", "venue_id":"0", "additional_attendee_reg_info":"3", "add_attendee_question_groups":{ "1":"1", "11":"11" }, "date_submitted":"June 18, 2012", "event_hashtag":"", "event_format":"", "event_livestreamed":"", "":"" } }, "Attendee":{ "id":"9273", "firstname":"aaa", "lastname":"aaa", "address":"", "address2":"", "city":"", "state":"", "country":"", "zip":"", "email":"", "phone":"" }, "Transaction":{ "id":"9273", "timestamp":"2012-10-22 21:14:04", "total":"536.66", "paid":"0.00", "status":"pending", "details":null, "tax_data":null, "session_data":null }, "Datetime":{ "id":"120", "is_primary":true, "event_start":"2012-10-31 08:00:00", "event_end":"2012-10-31 17:00:00", "registration_start":"2012-07-01 00:01:00", "registration_end":"2012-10-31 23:59:00", "limit":"0", "tickets_left":"500" }, "Price":{ "id":"154.0", "name":"General Admission", "amount":"0.01", "description":null, "limit":"500", "remaining":999999, "start_date":null, "end_date":null, "Pricetype":{ "id":1, "name":"Base Price", "is_member":false, "is_discount":false, "is_tax":false, "is_percent":false, "is_global":true, "order":0 } } }, { "id":"9274", "status":"approved", "date_of_registration":"2012-10-22 21:14:04", "final_price":"0.01", "code":"1-50860b7c7d415", "url_link":null, "is_primary":true, "is_group_registration":false, "is_going":true, "is_checked_in":false, "Event":{ "id":"1", "name":"Jump Til You Drop", "description":"This is a test. <!--more-->\r\n\r\n[ESPRESSO_VENUE]", "status":"active", "limit":"500", "group_registrations_allowed":true, "group_registrations_max":"10", "active":true, "member_only":false, "virtual_url":"", "call_in_number":"", "phone":"", "metadata":{ "default_payment_status":"", "venue_id":"0", "additional_attendee_reg_info":"3", "add_attendee_question_groups":{ "1":"1", "11":"11" }, "date_submitted":"June 18, 2012", "event_hashtag":"", "event_format":"", "event_livestreamed":"", "":"" } }, "Attendee":{ "id":"9274", "firstname":"aaa", "lastname":"aaa", "address":"", "address2":"", "city":"", "state":"", "country":"", "zip":"", "email":"", "phone":"" }, "Transaction":{ "id":"9274", "timestamp":"2012-10-22 21:14:04", "total":"536.66", "paid":"0.00", "status":"pending", "details":null, "tax_data":null, "session_data":null, }, "Datetime":{ "id":"120", "is_primary":true, "event_start":"2012-10-31 08:00:00", "event_end":"2012-10-31 17:00:00", "registration_start":"2012-07-01 00:01:00", "registration_end":"2012-10-31 23:59:00", "limit":"0", "tickets_left":"500" }, "Price":{ "id":"154.0", "name":"General Admission", "amount":"0.01", "description":null, "limit":"500", "remaining":999999, "start_date":null, "end_date":null, "Pricetype":{ "id":1, "name":"Base Price", "is_member":false, "is_discount":false, "is_tax":false, "is_percent":false, "is_global":true, "order":0 } } } ] } }
GET /registrations/{id}
gets a single registration and its related attendee, transaction, event, datetime, and price (and pricetype), where {id} is the registration_id. It does not accept query string variables
Example Request
mysite.com/espresso-api/v1/registrations/9273/{session_key}?
Example Response
{ "status":"OK", "status_code":200, "body":{ "Registration":{ "id":1.1, "status":"approved", "date_of_registration":"2012-12-10 16:12:31", "final_price":10, "code":"1-50c67a6f172e1", "url_link":null, "is_primary":true, "is_group_registration":true, "is_going":true, "is_checked_in":true, "Event":{ "id":1, "code":"1-50c679c10fcf0", "name":"testevent1", "description":"", "status":"active", "limit":999999, "group_registrations_allowed":true, "group_registrations_max":3, "active":true, "member_only":false, "virtual_url":"", "call_in_number":"", "phone":"", "metadata":{ "default_payment_status":"", "venue_id":"", "additional_attendee_reg_info":3, "add_attendee_question_groups":{ "1":"1" }, "date_submitted":"December 11, 2012", "event_hashtag":"", "event_format":"", "event_livestreamed":"", "":"" } }, "Attendee":{ "id":1, "firstname":"wef", "lastname":"few", "address":"", "address2":"", "city":"", "state":"", "country":"", "zip":"", "email":"michael@eventespresso.com", "phone":"" }, "Transaction":{ "id":1, "timestamp":"2012-12-10 16:12:31", "total":10, "amount_paid":0, "status":"pending", "details":null, "tax_data":null, "session_data":null, "payment_gateway":"Check" }, "Datetime":{ "id":21, "is_primary":true, "event_start":"2012-12-11 09:00:00", "event_end":"2012-12-10 17:00:00", "registration_start":"2012-12-09 00:01:00", "registration_end":"2016-12-21 23:59:00", "limit":999999, "tickets_left":999983 }, "Price":{ "id":0, "name":"Unknown", "amount":10, "description":null, "limit":9999999, "remaining":999999, "start_date":null, "end_date":null, "Pricetype":{ "id":1, "name":"Base Price", "is_member":false, "is_discount":false, "is_tax":false, "is_percent":false, "is_global":true, "order":0 } } } } }
GET/POST/PUT /registrations/{id}/checkin
Marks the registration with {id} as checked-in. If that registration is already checked in, checks in another registration which has
the same attendee and event. Returns the list of registrations that were checked in. Accepts the following query string parameters:
ignorePayment: boolean quantity: (integer), using a quantity of 3 is equivalent to issuing the same checkin request 3 times.
Example Request
GET/POST/PUT mysite.com/espresso-api/v1/registrations/9273/checkin{session_key}
Example Response
Returns the updated registrations just like GET /registrations (not a single registration, for reasons mentioned above)
Note: if the payment has not been verified, the registration will not be marked as checked-in, and the following response will be sent:
{"status":"Checkin denied. Payment not complete and 'ignorePayment' flag not set.","status_code":500}
GET/POST/PUT /registrations/{id}/checkout
Marks the registration with {id} as checked-out. If that registration is already checked out, checks out another registration which has
the same attendee and event. Returns the list of registrations that were checked out. Accepts the following query string parameters:
quantity: (integer), using a quantity of 3 is equivalent to issuing the same checkout request 3 times.
Example Request
GET/POST/PUT mysite.com/espresso-api/v1/registrations/9273/checkout/{session_key}
Example Response
Returns a list of updated registrations just like GET /registrations (not a single registration, for reasons mentioned above)
POST/PUT /registrations
Creates or updates the listed registrations. The request should be sent in an almost identical format as what’s received from GET /registrations
When submitting this request to create/update the listed registrations, currently ALL fields received on GET /registrations must also be submitted.
(There are plans to have some fields set to default values, and to not require all fields on updates, but those are not yet implemented).
Example Request
POST /registrations //with POST form data/post parameter 'body' containing all the json/xml received in the 'body' section of the response from GET /registrations (ie, don't include 'status' or 'status_code') body:{ "Registrations":[ { "id":"temp-new-one", "status":"not_approved", "date_of_registration":"2012-12-10 16:12:31", "final_price":10, "code":"1-50c67a6f172e1", "url_link":null, "is_primary":true, "is_group_registration":false, "is_going":true, "is_checked_in":true, "Event":{ "id":1, "code":"1-50c679c10fcf0", "name":"testevent1", "description":"", "status":"active", "limit":999999, "group_registrations_allowed":true, "group_registrations_max":3, "active":true, "member_only":false, "virtual_url":"", "call_in_number":"", "phone":"", "metadata":{ "default_payment_status":"", "venue_id":"", "additional_attendee_reg_info":3, "add_attendee_question_groups":{ "1":"1" }, "date_submitted":"December 11, 2012", "event_hashtag":"", "event_format":"", "event_livestreamed":"", "":"" } }, "Attendee":{ "id":"temp-new-one2", "firstname":"fromapi", "lastname":"fromapiman", "address":"", "address2":"", "city":"", "state":"", "country":"", "zip":"", "email":"michael@eventespresso.com", "phone":"" }, "Transaction":{ "id":"temp-new-one3", "timestamp":"2012-12-10 16:12:31", "total":10, "amount_paid":0, "status":"pending", "details":null, "tax_data":null, "session_data":null, "payment_gateway":"Check" }, "Datetime":{ "id":20, "is_primary":true, "event_start":"2012-12-11 09:00:00", "event_end":"2012-12-10 17:00:00", "registration_start":"2012-12-09 00:01:00", "registration_end":"2016-12-21 23:59:00", "limit":999999, "tickets_left":999984 }, "Price":{ "id":12, "name":"General Admission", "amount":10, "description":null, "limit":9999999, "remaining":999999, "start_date":null, "end_date":null, "Pricetype":{ "id":1, "name":"Base Price", "is_member":false, "is_discount":false, "is_tax":false, "is_percent":false, "is_global":true, "order":0 } } } ] }
The above request will create a new Registration, new Attendee, and new Transaction. It will also associate the new
Registration with Price with ID 12, with the Event with ID 1, and the Datetime with ID 20. It will also simultaneously update each of those
related models: the Price, Event and Datetime (in case you’d rather not update those related models, in teh future you will only need to provide their IDs, but
not all their attributes).
Note that in order to create a registration (or any other related model) you simply provide a ‘temporary id’ titled ‘temp-{whatever}’,
(the above registration’s temporary id is ‘temp-new-one’, the attendee’s is ‘temp-new-one2’. Please see the above section on ‘POSTing using Temporary IDs’ for more info).
If you instead wanted to simply update a registration with ID {id}, then you’d provide it as the ID instead of the above temporary id.
When the request is completed, the newly-created registrations (and their associated Attendee, Transaction, Event, Price and Datetime) will be returned
in exactly the same format as GET /registrations.
PUT /registrations/{id}
Updates the registration (and associated Attendee, Transaction, Event, Datetime, and Price) with id {id}. The request’s body should be
in the same format as GET /registrations/{id} (except without the ‘status’ and ‘status_code’), and the updated registration (and related models) will be returned.
Example Request
{ "Registration":{ "id":1.1, "status":"not_approved", "date_of_registration":"2012-12-10 16:12:31", "final_price":10, "code":"1-50c67a6f172e1", "url_link":null, "is_primary":true, "is_group_registration":false, "is_going":true, "is_checked_in":true, "Event":{ "id":1, "code":"1-50c679c10fcf0", "name":"testevent1", "description":"", "status":"active", "limit":999999, "group_registrations_allowed":true, "group_registrations_max":3, "active":true, "member_only":false, "virtual_url":"", "call_in_number":"", "phone":"", "metadata":{ "default_payment_status":"", "venue_id":"", "additional_attendee_reg_info":3, "add_attendee_question_groups":{ "1":"1" }, "date_submitted":"December 11, 2012", "event_hashtag":"", "event_format":"", "event_livestreamed":"", "":"" } }, "Attendee":{ "id":1, "firstname":"wef", "lastname":"few", "address":"", "address2":"", "city":"", "state":"", "country":"", "zip":"", "email":"michael@eventespresso.com", "phone":"" }, "Transaction":{ "id":1, "timestamp":"2012-12-10 16:12:31", "total":10, "amount_paid":0, "status":"pending", "details":null, "tax_data":null, "session_data":null, "payment_gateway":"Check" }, "Datetime":{ "id":20, "is_primary":true, "event_start":"2012-12-11 09:00:00", "event_end":"2012-12-10 17:00:00", "registration_start":"2012-12-09 00:01:00", "registration_end":"2016-12-21 23:59:00", "limit":999999, "tickets_left":999984 }, "Price":{ "id":0, "name":"Unknown", "amount":10, "description":null, "limit":9999999, "remaining":999999, "start_date":null, "end_date":null, "Pricetype":{ "id":1, "name":"Base Price", "is_member":false, "is_discount":false, "is_tax":false, "is_percent":false, "is_global":true, "order":0 } } } }
The above request will update registration with id 1.1, and update all it’s fields to the supplied values. Note: it will also update the related
Attendee, Transaction, Event, Datetime and Price (in future you will only need to provide the ID). Currently, if you don’t want to update the related models, don’t provide them at all.
For example, the following request updates only registration information (and leave related models untouched).
{ "Registration":{ "id":1.1, "status":"not_approved", "date_of_registration":"2012-12-10 16:12:31", "final_price":10, "code":"1-50c67a6f172e1", "url_link":null, "is_primary":true, "is_group_registration":false, "is_going":true, "is_checked_in":true } }
Attendees
GET /attendees
Gets all attendees and their related registrations and events
id int firstname: string lastname: string address: string address2: string city: string state: string country: string zip: string email: string phone: string comments: string (in Event Espresso 3.1, this will always be blank) notes: string (in Event Espresso 3.1, this will always be blank) Registrations: list of tuples, like toplevel results of GET /registrations Events: list of tuples, like toplevel results of GET /events
Unfinished Endpoints
These are endpoints that are not yet finished. However, you may want to know their response format when querying a related object, as they will eb part of teh response.
For example, although the endpoint espresso-api/v1/prices/{session_key} is not yet accessible, prices are returned with every request to espresso-api/v1/events/{session_key}, and so you’d
probably like to know what attributes to expect in responses and which are available for querying.
Prices
GET /prices
all prices.
id: float (not int!). eg: 1.1, 1.2, 1.3, OR 1, 1234, etc. Event: event like GET /events Pricetype: tuple like GET /pricetypes amount: string, eg: “10.2” name: string description: string limit: int remaining: int start_date: date end_date: date
Note: if a price is returned as a related object of the one you queried (eg, you queried “events”, and got a related “price”)
then we avoid infinite recursion by not returning an “Event” object nested inside the “price” object.
Price Types
GET /pricetypes
In 3.1, there are 4 immutable price types: “Base Price”,”Surcharge Amount”,”Surcharge Percent”, and “Member Price”, which are stored
in the code and not the database
id: int name: string is_member: boolean is_discount: boolean is_tax: boolean is_percent: boolean is_global: boolean order: boolean
Categories
GET /categories
gets all categories
id: int name: string identifier :string description: string user: int (creator)
Promo codes
GET /promocodes
Gets all promo (discount) codes
id: int coupon_code: string amount: string (like "10.23") use_percentage: boolean description: string apply_to_each_attendee: boolean quantity_available: int expiration_date: date user: int (creator's wordpress id)
Date times
GET /datetimes
gets all date/times. in 3.1, this is a combination of times in events_details and events_start_end tables
id: int Event: tuple like GET /events is_primary: boolean event_start: datetime event_end: datetime registration_start: datetime registration_end: datetime limit: int tickets_left: int
Venues
GET /venues
Gets all venues
id: int name: string identifier: string address: string address2: string city: string state: string zip: string country: string metas: key-values like “metas”:{“{meta_key}”:{meta_value},....} user: int
Transactions
GET /transactions
gets all transactions (in 3.1, this is a subset of columns from the /attendees table)
id: string (NOT int) timestamp: datetime total: decimal like 20.35 amount_paid: decimal status: one of “complete”,”open”,”pending” details: tuples like {“{meta_key}”:{value}} tax_data: tuples like {“{meta_key}”:{value}} session_data: tuples like {“{meta_key}”:{value}} Registrations: tuple like GET /registrations payment_gateway: string (indicating how the transaction was paid)
Caching and Counting
If you want to optimize your api client, you can utilize Event Espresso’s internal caching on any query. This is useful is you need to run a large query (eg, mysite.com/espresso-api/v1/registrations/{sessionkey}?limit=1000) which could potentially overburden the server, you want to get a count of items, or you want to implement pagination.
To do so, issue your query with an added query parameter of ‘cache_result’ (eg: mysite.com/espresso-api/v1/events/{session_key}?id__gt=10&limit=500&cache_result=true).
You will receive a response with a body containing the count of how many objects would be returned, an a cached_result_key like the following:
"count":16,"cached_result_key":"mafvjm903a59ms9schb2yglmysouw4sv72orjyao"
Instead of sending the entire response, we’ve just sent you a count of how many objects would be returned, and internally cached the result.
To access that cache, send a query to
{wordpress_site}/espresso-api/v1/cachedresults/{cached_result_key}/{session_key}
This will return a response exactly like your original query would have had you not added the ‘cache_result’ query parameter.
Also, when querying the cache you may add a special ‘limit’ query parameter to limit how much of the response is sent. Eg:
{wordpress_site}/espresso-api/v1/cachedresults/{cached_result_key}/{session_key}?limit=10
which will only return the first 10 objects. Just like the MYSQL ‘limit’ clause, you can also add a second value to ‘limit’ to
use an offset and limit. Eg ‘?limit=30,15’ will return 15 objects starting at the 30th one.
Permissions
The following users have permission to access the following resources. Public users can never update or create any resources, but they do have permissions to view certain resources, when “Public API Access” is enabled (Note: some of these roles are in the Event Espresso Permissions and Permission Pro plugins)
Version 2.1.x+ permissions
Integration with the Roles & Permission plugins (basic and pro) was significantly improved in this version. Basically, users should have access to the exact same resources via the API as they do via the normal web interface. E.g., if an Event Manager has permission to edit only events they create from wp-admin and only permission to view only active events on the website’s frontend event-list page, then in the JSON API when they submit a request to mysite.com/espresso-api/v1/events/{session_key}?editable_only=true then they should only see their events, and a request to mysite.com/espresso-api/v1/events/{session_key}?editable_only=false then they should see all active events (see below for a description of the “editable_only” query parameter added in version 2.1.0).
Also, the Roles & Permissions “Minimum Page Permissions” setting also applies users’ permissions in the JSON API. E.g., if you set the “Minimum Page Permission” for “Event/Attendee Listings Page” to “Master Admin”, then Event Managers and Regional Managers won’t be able to see either the Event Espresso Event Listing Page, or access mysite.com/espresso-api/v1/events/{session_key}.
Resource | R&P associated “Minimum Page Permission” | Public | Event Managers | Regional Manager | Event Master Admins & WP Admins | |||||
View | Edit | View | Edit | View | Edit | View | Edit | |||
events | Event/Attendee Listings Page | active only | none | all active or owned | owned | all active, owned, or in region | owned or in region | all | all | |
venues | Venue Manager Page | all | none | all | all | all | all | all | all | |
categories | Categories Page | all | none | all | all | all | all | all | all | |
datetimes | Event/Attendee Listings Page | all | none | all | for owned events | all | for events owned & in region | all | all | |
prices | Event/Attendee Listings Page | all non-member prices | none | all | for events owned | all | for events owned & in region | all | all | |
pricetypes | Event/Attendee Listings Page | all non-member prices | none | all | all | all | all | all | all | |
registrations | Event/Attendee Listings Page | none | none | for events owned | for events owned | for events owned & in region | for events owned & in region | all | all | |
attendees | Event/Attendee Listings Page | none | none | for registrations for events owned | for registrations for events owned | for registrations for events owned & in region | for registrations for events owned & in region | all | all | |
transactions | Event/Attendee Listings Page | none | none | for registrations for events owned | for registrations for events owned | for registrations for events owned & in region | for registrations for events owned & in region | all | all | |
answers | Event/Attendee Listings Page | none | none | for registrations for events owned | for registrations for events owned | for registrations for events owned & in region | for registrations for events owned & in region | all | all | |
promocodes | Discounts Page | none | none | all | all | all | all | all | all |
As of the JSON API plugin version 2.1, the query parameter ‘editable_only’ is available, accepting either ‘true’ or ‘false’ as values. It can be added to any GET request in order to filter out any results the current user CANNOT edit. For example, if you wanted to only see all the events the current user can edit, you could send a request like mysite.com/espresso-api/v1/events/{session_key}?editable_only=true. Also, there is a setting titled “Show API Users Data They Can’t Edit” in the JSON API Settings page (when the Roles&Permissions add-on is also active) which sets the default for this query parameter.
Version 2.0.x permissions
(This version only provided limited support of Roles an Permissions. E.g., Event Managers could use the API to view events they normally didn’t have permission to see.)
Resource | Public | Event Managers | Regional Manager | Event Master Admins | Admin |
events | only active and public events | yes | yes | yes | yes |
venues | yes | yes | yes | yes | yes |
categories | yes | yes | yes | yes | yes |
datetimes | yes | yes | yes | yes | yes |
venues | yes | yes | yes | yes | yes |
prices | yes | yes | yes | yes | yes |
pricetypes | yes | yes | yes | yes | yes |
registrations | no | yes | yes | yes | yes |
attendees | no | yes | yes | yes | yes |
transactions | no | yes | yes | yes | yes |
answers | no | yes | yes | yes | yes |
promocodes | no | yes | yes | yes | yes |
Status Codes
Along with each response, there is both a ‘status’ and a ‘status_code’. These status codes should more-or-less correspond to normal HTTP status codes. They are as follows:
Status Code | Status | Details |
---|---|---|
200 | OK | Your request was successfully processed. If you requested an object, it should have been returned in the ‘body’ attribute. If you did a PUT, POST, or DELETE, it should have succeeded, and the updated/created/deleted object should have been returned in the ‘body’ parameter |
400 | {various messages} | something about your request was illegal. You probably did a GET with an illegal query parameter |
403 | You are not authorized to access that endpoint | Your session has probably expired and you need to re-authenticate/login. It’s also possible that you simply do not have sufficient permissions to access that specific endpoint. Eg: if you’re logged in as a event manager and only have event ID 123 assigned to you, then you can’t update event 987 and will get this same response. |
404 | Request is ok, but there is no object of specified type with id: {id} | You made a request (like GET, PUT, or DELETE) on a specific resource (eg, /events/13), but that resource didn’t exist. Your request would have worked if the resource existed |
412 | {various messages} | Your request was syntactically correct and all, but some precondition failed before your request could be fully processed as you wanted. Example: you tried to check a registrant into an event using /registrations/13/checkin, but they hadn’t paid yet. Capice? |
500 | {various messages} | Some internal error occured. Your request was fine but our server software just died for some reason. If the response is specifically “Endpoint not yet implemented” then we just haven’t finished working on that endpoint. Hassle Event Espresso to get it implemented. |
Code Examples
Here are some examples of code that uses the API.
Summary and Link | Description |
---|---|
Upcoming Events | PHP code that fetches all upcoming events and displays them. Can be run from any domain. |
Upcoming Events w/ Calendar | PHP and HTML code that fetches all upcoming events and displays them in a calendar. Can be run from any domain. |
Past Events | PHP code that fetches all past evens and displays them. Can be run from any domain. |
Upcoming Events with Caching | PHP code that fetches all upcoming events, caches them, and displays them. Using caching can speed up your app, but requires a few more lines of code. Can be run from any domain. |
Past Events with Caching | PHP code that fetches all past events, caches them, and displays them. Using caching can speed up your app, but requires a few more lines of code. Can be run from any domain. |
Future Developments
POST /events
(create new event)
/events/{id}/questions
POST /events/{id}/attendees
GET/questions/{id}/answer
…etc
https://eventespresso.com/product/espresso-json-api/