{"id":1960250,"date":"2024-05-21T12:07:38","date_gmt":"2024-05-21T16:07:38","guid":{"rendered":"https:\/\/theeventscalendar.com\/knowledgebase\/?p=1960250"},"modified":"2026-04-15T16:26:41","modified_gmt":"2026-04-15T20:26:41","slug":"event-ticket-rest-api","status":"publish","type":"post","link":"https:\/\/theeventscalendar.com\/knowledgebase\/event-ticket-rest-api\/","title":{"rendered":"Events &amp; Tickets REST API"},"content":{"rendered":"\n<p>The Events Calendar and Event Tickets include a built-in REST API that lets you read, create, update, and delete event data from outside WordPress \u2014 whether from a mobile app, an external site, a script, or another service. This article covers what a REST API is, how the TEC endpoints are structured, how to make your first requests, how to authenticate, how to create events via POST, how to customize API responses, and how to explore the full self-documenting API reference on your own site.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-what-is-a-rest-api\">What is a REST API<\/h2>\n\n\n\n<p>REST (<strong>RE<\/strong>presentation <strong>S<\/strong>tate <strong>T<\/strong>ransfer) API (<strong>A<\/strong>pplication <strong>P<\/strong>rogramming <strong>I<\/strong>nterface) is a great tool for enabling communication and data exchange between your site and other applications or services using standard web protocols. REST APIs typically use JSON (<strong>J<\/strong>ava<strong>S<\/strong>cript <strong>O<\/strong>bject <strong>N<\/strong>otation) for data interchange \u2014 a lightweight format that is easy for humans to read and easy for machines to parse.<\/p>\n\n\n\n<p>The &#8220;REST&#8221; part means that the state of each transaction between a client and the server is wholly contained in the response the client receives. HTTP protocol-based communications are the domain where REST APIs live, and they make full use of HTTP methods:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>GET<\/code> \u2014 retrieve data from the server<\/li>\n\n\n\n<li><code>POST<\/code> \u2014 send new data to the server (create)<\/li>\n\n\n\n<li><code>PUT<\/code> \/ <code>PATCH<\/code> \u2014 update existing data on the server<\/li>\n\n\n\n<li><code>DELETE<\/code> \u2014 remove data from the server<\/li>\n<\/ul>\n\n\n\n<p>Almost any REST API \u2014 including WordPress and The Events Calendar \u2014 uses authorization to allow or restrict what a user can do. <code>GET<\/code> requests are often public; operations that create, update, or delete data typically require authentication. HTTP response codes tell you what happened: <code>200<\/code> means success, <code>404<\/code> means not found, <code>403<\/code> means not authorized, <code>500<\/code> means a server error occurred. See the <a href=\"https:\/\/en.wikipedia.org\/wiki\/List_of_HTTP_status_codes\">full list of HTTP status codes<\/a> for reference.<\/p>\n\n\n\n<p>For more background on the WordPress REST API specifically:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/developer.wordpress.org\/rest-api\/\">REST API Handbook<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/developer.wordpress.com\/docs\/api\/\">Endpoints<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/kinsta.com\/blog\/wordpress-rest-api\/\">Beginner Guide<\/a><\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-the-events-calendar-rest-api\">The Events Calendar REST API<\/h2>\n\n\n\n<p>We built The Events Calendar REST API to allow our users and ourselves to consume and manage events <strong>from anywhere<\/strong>. In its most basic form, a REST API separates the content from its presentation, freeing developers and users from the constraints of a WordPress site and a WordPress theme. Some examples of what this enables:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Themes can access events, venues, and organizers&#8217; data without using plugin PHP functions \u2014 developers can present that data in any way they want.<\/li>\n\n\n\n<li>Sites not using PHP or WordPress can use a WordPress installation as a CMS to manage events while the front-end is maintained in a different language or framework.<\/li>\n\n\n\n<li>Android, iOS, and other mobile developers can use a WordPress backend to manage events and present the same information across different platforms.<\/li>\n\n\n\n<li>External applications and services can create, update, or sync events directly into your site programmatically.<\/li>\n<\/ul>\n\n\n\n<p>Since The Events Calendar REST API is built on top of the <a href=\"https:\/\/developer.wordpress.org\/rest-api\/\">WordPress REST API<\/a>, it inherits its code, robustness, and security.<\/p>\n\n\n\n<p>The Events Calendar REST API is free and bundled with The Events Calendar plugin. It requires WordPress 4.5 or above. Once you have installed and activated The Events Calendar, you are ready to get started.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-endpoints-and-base-url\">Endpoints and Base URL<\/h2>\n\n\n\n<p>All TEC REST API calls follow the same URL structure. For events:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n&#x5B;your-site-URL]\/wp-json\/tribe\/events\/v1\/{endpoint}\n<\/pre><\/div>\n\n\n<p>Breaking this down:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>[your-site-URL]\/<\/code> \u2014 the server you are making the request to<\/li>\n\n\n\n<li><code>\/wp-json\/tribe\/events\/v1<\/code> \u2014 <code>\/wp-json<\/code> is the WordPress Core REST API prefix; <code>\/tribe\/events\/v1<\/code> identifies The Events Calendar plugin and API version<\/li>\n\n\n\n<li><code>\/{endpoint}<\/code> \u2014 optional, adds specificity to what the call returns (e.g. <code>\/events<\/code>, <code>\/events\/6<\/code>, <code>\/venues<\/code>)<\/li>\n<\/ul>\n\n\n\n<p>To access the tickets API instead of events, switch <code>\/events<\/code> for <code>\/tickets<\/code>:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n&#x5B;your-site-URL]\/wp-json\/tribe\/tickets\/v1\/{endpoint}\n<\/pre><\/div>\n\n\n<p>For the full list of available endpoints for both events and tickets, see the <a href=\"https:\/\/docs.theeventscalendar.com\/rest-endpoints\/\">REST API endpoints documentation<\/a>. You can also explore all available endpoints on your own site by visiting <code>\/wp-json\/tribe\/events\/v1\/doc<\/code> \u2014 more on this in the <a href=\"#swagger\">Self-Documenting API Reference<\/a> section below.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"h-example-get-requests\">Example GET Requests<\/h4>\n\n\n\n<p>The simplest request is a <code>GET<\/code> to return all events. You can test this by pasting the URL directly into your browser:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nGET https:\/\/demo.theeventscalendar.com\/wp-json\/tribe\/events\/v1\/events\n<\/pre><\/div>\n\n\n<p>This returns a JSON response that looks like this (truncated for brevity):<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n{\n  &quot;events&quot;: &#x5B;\n    {\n      &quot;id&quot;: 1762,\n      &quot;global_id&quot;: &quot;demo.theeventscalendar.com?id=1762&quot;,\n      &quot;author&quot;: &quot;2&quot;,\n      &quot;status&quot;: &quot;publish&quot;,\n      &quot;date&quot;: &quot;2022-12-01 12:36:40&quot;,\n      &quot;url&quot;: &quot;https:\/\/demo.theeventscalendar.com\/event\/hosted-dinner-with-chef-monica-geller\/&quot;,\n      &quot;rest_url&quot;: &quot;https:\/\/demo.theeventscalendar.com\/wp-json\/tribe\/events\/v1\/events\/1762&quot;,\n      &quot;title&quot;: &quot;Hosted Dinner with Chef Monica Geller&quot;,\n      &quot;description&quot;: &quot;&amp;lt;p&gt;Join Chef Monica Geller for a Hosted Dinner!&amp;lt;\/p&gt;&quot;,\n      &quot;all_day&quot;: false,\n      &quot;start_date&quot;: &quot;2017-09-21 08:00:00&quot;,\n      &quot;end_date&quot;: &quot;2017-09-21 17:00:00&quot;,\n      &quot;timezone&quot;: &quot;UTC+0&quot;,\n      &quot;cost&quot;: &quot;$5&quot;,\n      &quot;categories&quot;: &#x5B;...],\n      &quot;tags&quot;: &#x5B;...],\n      &quot;venue&quot;: {...},\n      &quot;organizer&quot;: &#x5B;...]\n    }\n  ],\n  &quot;rest_url&quot;: &quot;...&quot;,\n  &quot;total&quot;: 1,\n  &quot;total_pages&quot;: 1\n}\n<\/pre><\/div>\n\n\n<p>To return a single event, pass its post ID as a path parameter:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nGET https:\/\/demo.theeventscalendar.com\/wp-json\/tribe\/events\/v1\/events\/1762\n<\/pre><\/div>\n\n\n<p>Many of the WordPress and TEC REST API parameters share names with those used in <a href=\"https:\/\/developer.wordpress.org\/reference\/classes\/wp_query\/\"><code>WP_Query<\/code><\/a>. You can use standard query parameters to filter results \u2014 for example, <code>per_page<\/code> and <code>page<\/code> for pagination:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nGET https:\/\/demo.theeventscalendar.com\/wp-json\/tribe\/events\/v1\/events?per_page=2&amp;amp;page=2\n<\/pre><\/div>\n\n\n<h4 class=\"wp-block-heading\" id=\"h-query-parameter-example-tickets\">Query Parameter Example: Tickets<\/h4>\n\n\n\n<p>The same approach works for the tickets endpoint. For example, to return only tickets that have Individual Attendee Collection enabled:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nGET https:\/\/demo.theeventscalendar.com\/wp-json\/tribe\/tickets\/v1\/tickets?attendee_information_available=true\n<\/pre><\/div>\n\n\n<p>\ud83d\udc4b You may notice that the <code>attendees<\/code> attribute for each ticket returns as an empty array even when you know attendees exist. This is because attendee data requires authentication to retrieve \u2014 see the <a href=\"#authentication\">Authentication<\/a> section below.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-authentication\">Authentication<\/h2>\n\n\n\n<p>Some REST API requests require authentication to return data. For example, this endpoint is valid:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nGET https:\/\/demo.theeventscalendar.com\/wp-json\/tribe\/tickets\/v1\/attendees\n<\/pre><\/div>\n\n\n<p>But without authentication, a site with attendees will still return:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n{\n  &quot;rest_url&quot;: &quot;https:\/\/demo.theeventscalendar.com\/wp-json\/tribe\/tickets\/v1\/attendees\/&quot;,\n  &quot;total&quot;: 0,\n  &quot;total_pages&quot;: 0,\n  &quot;attendees&quot;: &#x5B;]\n}\n<\/pre><\/div>\n\n\n<p>Since our REST API is built on top of the WordPress API, the same <a href=\"https:\/\/developer.wordpress.org\/rest-api\/using-the-rest-api\/authentication\/\">authentication practices<\/a> are baked in. This ensures that sensitive information \u2014 such as attendees&#8217; personal data \u2014 remains protected. Regardless of which method you choose, you are setting up a secret token that grants access to otherwise protected information or actions.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"h-authentication-methods\">Authentication Methods<\/h4>\n\n\n\n<p>Three options are available:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong><a href=\"https:\/\/github.com\/WP-API\/Basic-Auth\">Basic Auth plugin<\/a><\/strong> \u2014 Recommended for simple authentication. Allows you to use your WordPress admin credentials for API requests.<\/li>\n\n\n\n<li><strong><a href=\"https:\/\/wordpress.org\/plugins\/jwt-authentication-for-wp-rest-api\/\">JWT Authentication plugin<\/a><\/strong> \u2014 For more advanced JSON Web Token authentication.<\/li>\n\n\n\n<li><strong>Nonce Authentication<\/strong> \u2014 Create a nonce using <code>wp_create_nonce()<\/code> with the action set to <code>'wp_rest'<\/code>. More technical to set up, but very versatile and built into WordPress.<\/li>\n<\/ol>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"h-making-a-request-with-curl-basic-auth\">Making a Request with cURL (Basic Auth)<\/h4>\n\n\n\n<p>With the Basic Auth plugin installed and activated, you can authenticate a <code>GET<\/code> request using cURL by passing your WordPress username and password with the <code>--user<\/code> flag:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\ncurl --user user:pass -X GET \\\n    -H &quot;Content-Type: application\/json&quot; \\\n    https:\/\/www.yoursite.url\/wp-json\/tribe\/tickets\/v1\/attendees\n<\/pre><\/div>\n\n\n<p>An authenticated response with one attendee looks like this:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n{\n  &quot;rest_url&quot;: &quot;https:\/\/stable.dev.lndo.site\/wp-json\/tribe\/tickets\/v1\/attendees\/&quot;,\n  &quot;total&quot;: 1,\n  &quot;total_pages&quot;: 1,\n  &quot;attendees&quot;: &#x5B;\n    {\n      &quot;id&quot;: 33,\n      &quot;post_id&quot;: 29,\n      &quot;ticket_id&quot;: 30,\n      &quot;title&quot;: &quot;Steve Harvey&quot;,\n      &quot;email&quot;: &quot;steve@example.com&quot;,\n      &quot;checked_in&quot;: false,\n      &quot;ticket&quot;: {\n        &quot;id&quot;: &quot;30&quot;,\n        &quot;title&quot;: &quot;Entree&quot;,\n        &quot;raw_price&quot;: 20,\n        &quot;formatted_price&quot;: &quot;20.00&quot;,\n        &quot;start_sale&quot;: &quot;2024-06-01&quot;,\n        &quot;end_sale&quot;: &quot;2024-07-01&quot;\n      },\n      &quot;payment&quot;: {\n        &quot;provider&quot;: &quot;woo&quot;,\n        &quot;price&quot;: 20,\n        &quot;currency&quot;: &quot;$&quot;,\n        &quot;date&quot;: &quot;2024-06-06 15:36:16&quot;\n      }\n    }\n  ]\n}\n<\/pre><\/div>\n\n\n<h4 class=\"wp-block-heading\" id=\"h-making-a-request-with-ajax-nonce\">Making a Request with AJAX (Nonce)<\/h4>\n\n\n\n<p>For front-end JavaScript usage, nonce authentication is the standard WordPress approach. In your PHP where the script is <a href=\"https:\/\/developer.wordpress.org\/reference\/functions\/wp_enqueue_script\/\">enqueued<\/a>, pass the nonce as a localized variable using <a href=\"https:\/\/developer.wordpress.org\/reference\/functions\/wp_localize_script\/\"><code>wp_localize_script()<\/code><\/a>:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n\/\/ Localize the script with the nonce\nwp_localize_script( &#039;handle-of-script&#039;, &#039;localized_script_variables&#039;, array(\n    &#039;ajax_url&#039;      =&gt; admin_url( &#039;admin-ajax.php&#039; ),\n    &#039;rest_endpoint&#039; =&gt; &#039;\/wp-json\/tribe\/tickets\/v1\/attendees\/&#039;,\n    &#039;nonce&#039;         =&gt; wp_create_nonce( &#039;wp_rest&#039; ),\n) );\n<\/pre><\/div>\n\n\n<p>Then in your JavaScript file, set the <code>X-WP-Nonce<\/code> header on the request:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n$.ajax({\n    url: localized_script_variables.ajax_url,\n    type: &#039;GET&#039;,\n    dataType: &#039;json&#039;,\n    headers: {\n        &#039;X-WP-Nonce&#039;: localized_script_variables.nonce,\n    },\n    success: renderAttendees\n});\n<\/pre><\/div>\n\n\n<p>You can test that authentication is working by triggering the AJAX call as a logged-in user versus in an incognito window.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"h-authentication-in-a-theme-full-javascript-example\">Authentication in a Theme: Full JavaScript Example<\/h4>\n\n\n\n<p>The following is a complete example of cookie-based nonce authentication used in a child theme to fetch and display events via the REST API. In <code>functions.php<\/code>, enqueue your script and localize the REST API root URL and nonce:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n\/\/ file functions.php\n\nadd_action( &#039;wp_enqueue_scripts&#039;, &#039;twentyseventeen_parent_theme_enqueue_styles&#039; );\n\nfunction twentyseventeen_parent_theme_enqueue_styles() {\n    wp_enqueue_style( &#039;twentyseventeen-style&#039;, get_template_directory_uri() . &#039;\/style.css&#039; );\n    wp_enqueue_style( &#039;rest-style&#039;,\n        get_stylesheet_directory_uri() . &#039;\/style.css&#039;,\n        array( &#039;twentyseventeen-style&#039; )\n    );\n\n    \/\/ Enqueue the theme script...\n    wp_enqueue_script( &#039;rest-theme-js&#039;, get_stylesheet_directory_uri() . &#039;\/js\/rest-theme.js&#039;, array( &#039;jquery&#039; ) );\n\n    \/\/ ...and localize The Events Calendar REST API root URL and nonce\n    wp_localize_script( &#039;rest-theme-js&#039;, &#039;restTheme&#039;,\n        array(\n            &#039;root&#039;  =&gt; esc_url_raw( tribe_events_rest_url() ),\n            &#039;nonce&#039; =&gt; wp_create_nonce( &#039;wp_rest&#039; )\n        )\n    );\n}\n<\/pre><\/div>\n\n\n<p>In <code>\/js\/rest-theme.js<\/code>, fetch and render the next 3 upcoming events when the page loads:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n( function( $ ) {\n    if ( undefined === restTheme ) {\n        return;\n    }\n\n    var renderEvents = function( response ) {\n        var eventsNode;\n\n        if ( response.events.length &gt; 0 ) {\n            eventsNode = $( &#039;&amp;lt;ul&gt;&#039; );\n            for ( var event of response.events ) {\n                var eventNode = $( &#039;&amp;lt;li&gt;&#039; );\n                eventNode.text( event.title );\n                eventNode.appendTo( eventsNode );\n            }\n        } else {\n            eventsNode = $( &#039;&amp;lt;p&gt;&#039; );\n            eventsNode.text( &#039;No upcoming events found!&#039; );\n        }\n\n        eventsNode.appendTo( $( &#039;#rest-events&#039; ) );\n    };\n\n    var showEvents = function() {\n        $.ajax( {\n            url: restTheme.root + &#039;events&#039;,\n            method: &#039;GET&#039;,\n            beforeSend: function( xhr ) {\n                xhr.setRequestHeader( &#039;X-WP-Nonce&#039;, restTheme.nonce );\n            },\n            data: { &#039;page&#039;: 1, &#039;per_page&#039;: 3 }\n        } ).done( renderEvents );\n    };\n\n    $( document ).ready( function() { showEvents(); } );\n} )( jQuery );\n<\/pre><\/div>\n\n\n<p>By default, visitors and subscribers see only public events. Users with the <code>edit_posts<\/code> capability (Editor, Administrator) will also see private and draft events \u2014 this is true for any authentication method, not just cookie-based.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-creating-events-via-post\">Creating Events via POST<\/h2>\n\n\n\n<p>The REST API supports creating new events by sending a <code>POST<\/code> request to the events endpoint. Because you are modifying data on the server, this operation requires authentication and appropriate user permissions (Editor or Administrator role).<\/p>\n\n\n\n<p>The examples below use <a href=\"https:\/\/developer.wordpress.org\/rest-api\/using-the-rest-api\/authentication\/#basic-authentication-with-application-passwords\">Application Passwords<\/a> for authentication. Application Passwords authenticate REST requests without exposing your main login password \u2014 they are per-user, revocable, and designed for use over HTTPS. If you prefer a different method, you can adapt the examples to use <a href=\"https:\/\/developer.wordpress.org\/rest-api\/using-the-rest-api\/authentication\/#cookie-authentication\">Cookie\/Nonce<\/a> authentication instead.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"h-prerequisites\">Prerequisites<\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li>WordPress 5.6 or above<\/li>\n\n\n\n<li>Site served over HTTPS (or a local development environment). Note: some hosts or security plugins may disable this feature.<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"h-generate-an-application-password\">Generate an Application Password<\/h4>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Log in to your WordPress dashboard with an Editor or Administrator account.<\/li>\n\n\n\n<li>Go to <strong>Users \u2192 Profile<\/strong>.<\/li>\n\n\n\n<li>Scroll to <strong>Application Passwords<\/strong>.<\/li>\n\n\n\n<li>Enter a descriptive name (e.g. &#8220;My Script&#8221; or &#8220;Zapier&#8221;) and click <strong>Add Application Password<\/strong>.<\/li>\n\n\n\n<li><strong>Copy the generated password now<\/strong> \u2014 you will not see it again. You can revoke it at any time from the same screen.<\/li>\n<\/ol>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"h-post-endpoint-reference\">POST Endpoint Reference<\/h4>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Detail<\/th><th>Value<\/th><\/tr><\/thead><tbody><tr><td>Method<\/td><td><code>POST<\/code><\/td><\/tr><tr><td>Endpoint<\/td><td><code>\/wp-json\/tribe\/events\/v1\/events<\/code><\/td><\/tr><tr><td>Authentication<\/td><td>Required (e.g. Application Passwords)<\/td><\/tr><tr><td>Content-Type<\/td><td><code>application\/json<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"h-required-parameters\">Required Parameters<\/h4>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Parameter<\/th><th>Type<\/th><th>Description<\/th><th>Example<\/th><\/tr><\/thead><tbody><tr><td><code>title<\/code><\/td><td>string<\/td><td>The title of the event<\/td><td>&#8220;Annual Developer Meetup&#8221;<\/td><\/tr><tr><td><code>start_date<\/code><\/td><td>string<\/td><td>Event start date and time<\/td><td>&#8220;2025-11-20 14:00:00&#8221;<\/td><\/tr><tr><td><code>end_date<\/code><\/td><td>string<\/td><td>Event end date and time<\/td><td>&#8220;2025-11-20 17:00:00&#8221;<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"h-setting-event-status\">Setting Event Status<\/h4>\n\n\n\n<p>By default, newly created events are saved as <code>draft<\/code>. To publish immediately, include the <code>status<\/code> parameter:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Parameter<\/th><th>Value<\/th><th>Result<\/th><\/tr><\/thead><tbody><tr><td><code>status<\/code><\/td><td><code>\"publish\"<\/code><\/td><td>Event is created and immediately published<\/td><\/tr><tr><td><code>status<\/code><\/td><td><code>\"draft\"<\/code><\/td><td>Event is saved as a draft (default)<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"h-example-json-payload\">Example JSON Payload<\/h4>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n{\n    &quot;title&quot;: &quot;REST API Event Creation Sample&quot;,\n    &quot;description&quot;: &quot;A deep dive into new features of The Events Calendar REST API.&quot;,\n    &quot;start_date&quot;: &quot;2025-11-20 09:00:00&quot;,\n    &quot;end_date&quot;: &quot;2025-11-20 11:30:00&quot;,\n    &quot;all_day&quot;: false,\n    &quot;status&quot;: &quot;publish&quot;,\n    &quot;website&quot;: &quot;https:\/\/your-site.com\/rest-api-workshop&quot;,\n    &quot;categories&quot;: &#x5B;12, 34]\n}\n<\/pre><\/div>\n\n\n<h4 class=\"wp-block-heading\" id=\"h-complete-curl-example\">Complete cURL Example<\/h4>\n\n\n\n<p>Replace <code>your-site.com<\/code>, <code>WP_USERNAME<\/code>, and <code>APPLICATION_PASSWORD<\/code> with your actual values. The <code>--user<\/code> flag automatically handles Basic Auth encoding.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\ncurl -X POST &#039;https:\/\/your-site.com\/wp-json\/tribe\/events\/v1\/events&#039; \\\n  --header &#039;Content-Type: application\/json&#039; \\\n  --user &#039;WP_USERNAME:APPLICATION_PASSWORD&#039; \\\n  --data-raw &#039;{\n    &quot;title&quot;: &quot;Event Created from REST API&quot;,\n    &quot;description&quot;: &quot;This event was created via a POST request to the events REST API.&quot;,\n    &quot;start_date&quot;: &quot;2025-11-25 10:00:00&quot;,\n    &quot;end_date&quot;: &quot;2025-11-25 11:00:00&quot;,\n    &quot;status&quot;: &quot;publish&quot;\n}&#039;\n<\/pre><\/div>\n\n\n<p>For the complete list of available fields and their data structures \u2014 including how to set Venues, Organizers, and other attributes \u2014 see the <a href=\"https:\/\/docs.theeventscalendar.com\/rest-endpoints\/\">REST API endpoints documentation<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-using-the-rest-api-to-manage-event-attendees\">Using the REST API to Manage Event Attendees<\/h2>\n\n\n\n<p>If you haven&#8217;t already, before diving into this guide you should start with our other articles about using the REST API with The Events Calendar and Event Tickets. Get started with the <a href=\"https:\/\/theeventscalendar.com\/knowledgebase\/event-ticket-rest-api-basics\/\" target=\"_blank\" rel=\"noreferrer noopener\">basics<\/a> and then learn how to add <a href=\"https:\/\/theeventscalendar.com\/knowledgebase\/rest-api-authentication\/\" target=\"_blank\" rel=\"noreferrer noopener\">authentication<\/a> to your requests. Up to this point, we&#8217;ve mostly been talking about just retrieving information (<code>GET<\/code> requests), but in this guide we&#8217;re going to dive into <code>POST<\/code> requests to create new attendees and <code>PUT<\/code> requests to update existing attendees.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"h-create-a-new-attendee\">Create a New Attendee<\/h4>\n\n\n\n<p>First, set up an authenticated call &#8211; in this example we&#8217;ll be using an <a href=\"https:\/\/theeventscalendar.com\/knowledgebase\/rest-api-authentication\/#h-making-a-rest-request-with-ajax\" target=\"_blank\" rel=\"noreferrer noopener\">authenticated AJAX call<\/a>. In your script file, this is what your JS will look like:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\n$.ajax( {\n\t\tmethod: &#039;POST&#039;,\n\t\turl: &#039;https:\/\/your-site\/wp-json\/tribe\/tickets\/v1\/attendees&#039;,\n\t\tbeforeSend: function ( xhr ) {\n\t\t\txhr.setRequestHeader( &#039;X-WP-Nonce&#039;, ajax_variable.nonce );\n\t\t},\n\t\tdata: {\n\t\t\tticket_id: &#039;50&#039;, \n\t\t\tfull_name: &#039;Bob Saget&#039;,\n\t\t\temail: &#039;bob@mail.com&#039;,\n\t\t}\n\t} )\n} );\n<\/pre><\/div>\n\n\n<p>Let&#8217;s break this down: <\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong><code>method: 'POST'<\/code> &#8211;<\/strong> This establishes that we want to add something new to the database (in this case, a new attendee).<\/li>\n\n\n\n<li><strong><code>url: \u2018https:\/\/your.site\/wp-json\/tribe\/tickets\/v1\/attendees\u2019<\/code> &#8211; <\/strong>This is the endpoint for the REST API. Make sure to replace &#8220;<code>your.site<\/code>&#8221; with your site&#8217;s actual URL. The rest of the endpoint is pointing to the Event Tickets API for attendees.<\/li>\n\n\n\n<li><strong><code>beforeSend: function (xhr)<\/code> &#8211; <\/strong>This function is used to add headers to the AJAX request. In this case, we are adding an authentication token (nonce) to the request, which is necessary to validate that the user making the request has the right permissions to create an attendee. Make sure you update the localized variable name (<code>ajax_variable.nonce<\/code>) if you used something different.<\/li>\n\n\n\n<li><strong><code>data: {\u2026}<\/code> &#8211;<\/strong> This is the body of the request, where you send the actual information needed to create the new attendee. Each key in the object corresponds to a required parameter expected by the API. There are other <a href=\"https:\/\/docs.theeventscalendar.com\/rest-endpoints\/?urls.primaryName=Tickets#\/default\/get_attendees\" target=\"_blank\" rel=\"noreferrer noopener\">attendee-specific parameters<\/a> you can optionally add, but these three are required:\n<ul class=\"wp-block-list\">\n<li><strong><code>ticket_id: \u201850\u2019<\/code> &#8211;<\/strong> The <code>ticket_id<\/code> is a string or integer that must correspond to the <code>post_id<\/code> of an existing ticket in your system. The attendee you\u2019re creating will be associated with this ticket. Without a valid <code>ticket_id<\/code>, the request will fail.<\/li>\n\n\n\n<li><strong><code>full_name: \u2018Bob Saget\u2019<\/code> &#8211;<\/strong> This is the name of the attendee you\u2019re creating. It will appear in the <a href=\"https:\/\/theeventscalendar.com\/knowledgebase\/tickets-managing-your-orders-and-attendees\/#attendee-list\" target=\"_blank\" rel=\"noreferrer noopener\">list of attendees associated with the event<\/a>.<\/li>\n\n\n\n<li><strong><code>email: \u2018bob@mail.com\u2019<\/code> &#8211; <\/strong>This is the attendee\u2019s email address. Make sure this is a valid email, as it will be used for communication and sending the tickets, which you will have to either send manually on the attendee page or through a different customization.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"h-update-an-existing-attendee\">Update an Existing Attendee<\/h4>\n\n\n\n<p>The process for updating an attendee is very similar to creating a new attendee with two key differences: the request type is a <code>PUT<\/code> request (instead of a <code>POST<\/code> request), and you have to identify which attendee you want to update in the REST API. <\/p>\n\n\n\n<p>To find the <code>id<\/code> of a given attendee, you can either use a <a href=\"https:\/\/theeventscalendar.com\/knowledgebase\/rest-api-authentication\/#h-making-a-rest-request-with-ajax\" target=\"_blank\" rel=\"noreferrer noopener\">REST API <code>GET<\/code> request<\/a>, or go to the Attendee Page and find the attendee you want to update and their <code>id<\/code> will be the number under their name:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"357\" src=\"https:\/\/images.theeventscalendar.com\/kb\/uploads\/2024\/10\/CleanShot-2024-10-23-at-17.01.45@2x-1024x357.png\" alt=\"\" class=\"wp-image-1963267\" srcset=\"https:\/\/images.theeventscalendar.com\/kb\/uploads\/2024\/10\/CleanShot-2024-10-23-at-17.01.45@2x-1024x357.png 1024w, https:\/\/images.theeventscalendar.com\/kb\/uploads\/2024\/10\/CleanShot-2024-10-23-at-17.01.45@2x-300x105.png 300w, https:\/\/images.theeventscalendar.com\/kb\/uploads\/2024\/10\/CleanShot-2024-10-23-at-17.01.45@2x-768x268.png 768w, https:\/\/images.theeventscalendar.com\/kb\/uploads\/2024\/10\/CleanShot-2024-10-23-at-17.01.45@2x-1536x535.png 1536w, https:\/\/images.theeventscalendar.com\/kb\/uploads\/2024\/10\/CleanShot-2024-10-23-at-17.01.45@2x-2048x714.png 2048w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>This is what the AJAX call looks like with those adjustments:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\n$.ajax( {\n\t\tmethod: &#039;PUT&#039;, \/\/ For updating existing item in database\n\t\turl: &#039;https:\/\/your-site\/wp-json\/tribe\/tickets\/v1\/attendees\/670&#039;, \/\/ Add the id of the attendee\n\t\tbeforeSend: function ( xhr ) {\n\t\t\txhr.setRequestHeader( &#039;X-WP-Nonce&#039;, ajax_variable.nonce );\n\t\t},\n\t\tdata: {\n\t\t\tticket_id: &#039;50&#039;, \n\t\t\tfull_name: &#039;Updated Name&#039;,\n\t\t\temail: &#039;updatedemail@mail.com&#039;,\n\t\t}\n\t} )\n} );\n<\/pre><\/div>\n\n\n<h2 class=\"wp-block-heading\" id=\"h-customizing-api-responses\">Customizing API Responses<\/h2>\n\n\n\n<p>The TEC REST API exposes filters you can use to modify what is returned in responses \u2014 for both events and the API documentation itself.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-adding-custom-fields-to-event-responses\">Adding Custom Fields to Event Responses<\/h3>\n\n\n\n<p>Use the <code>tribe_rest_single_event_data<\/code> filter to add custom meta fields to single-event responses. The following example adds a custom <code>_raccoon_suspect_level<\/code> meta field:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nadd_filter( &#039;tribe_rest_single_event_data&#039;, &#039;my_plugin_add_suspect_level&#039; );\n\nfunction my_plugin_add_suspect_level( array $event_data ) {\n    $event_id = $event_data&#x5B;&#039;id&#039;];\n    $level = get_post_meta( $event_id, &#039;_raccoon_suspect_level&#039;, true );\n\n    if ( empty( $level ) ) {\n        $level = &#039;4&#039;;\n    }\n\n    $event_data&#x5B;&#039;raccoon_suspect_level&#039;] = $level;\n    return $event_data;\n}\n<\/pre><\/div>\n\n\n<h3 class=\"wp-block-heading\" id=\"h-removing-fields-from-event-responses\">Removing Fields from Event Responses<\/h3>\n\n\n\n<p>The same filter can be used to remove fields you do not want returned. For example, to strip the <code>json_ld<\/code> data that is included in single-event responses:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nadd_filter( &#039;tribe_rest_single_event_data&#039;, &#039;my_plugin_remove_json_ld&#039; );\n\nfunction my_plugin_remove_json_ld( array $event_data ) {\n    unset( $event_data&#x5B;&#039;json_ld&#039;] );\n    return $event_data;\n}\n<\/pre><\/div>\n\n\n<p>Filters exist throughout the <code>src\/Tribe\/REST\/V1<\/code> folder of the plugin for events, venues, and organizers, so there is almost always a way to shape the response to your needs.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-self-documenting-api-reference\">Self-Documenting API Reference<\/h2>\n\n\n\n<p>The Events Calendar REST API includes a live documentation endpoint available on your own site:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nhttps:\/\/your-site.com\/wp-json\/tribe\/events\/v1\/doc\n<\/pre><\/div>\n\n\n<p>Hitting this endpoint returns a JSON object in <a href=\"https:\/\/swagger.io\/\">Swagger 2.0<\/a> format that documents every available endpoint, parameter, and response structure \u2014 and because it is generated from the code itself, it is always up to date.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/images.theeventscalendar.com\/kb\/uploads\/2017\/09\/swagger-output-665x408.png\" alt=\"The Events Calendar REST API documentation rendered in the Swagger.io editor\"\/><\/figure>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/images.theeventscalendar.com\/kb\/uploads\/2017\/09\/swagger-output-2-665x408.png\" alt=\"A second view of the Swagger.io documentation output for the TEC REST API\"\/><\/figure>\n\n\n\n<p>To use it, copy the entire JSON output from your <code>\/doc<\/code> endpoint and paste it into the <a href=\"https:\/\/editor.swagger.io\/\">Swagger.io online editor<\/a>. If prompted to convert JSON to YAML, click OK \u2014 after a moment you will see fully rendered, navigable documentation on the right side.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"h-documenting-custom-fields-in-swagger\">Documenting Custom Fields in Swagger<\/h4>\n\n\n\n<p>If you add custom fields to the response (as shown in the previous section), you can also document them in the Swagger output using the <code>tribe_rest_swagger_event_documentation<\/code> filter:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nadd_filter( &#039;tribe_rest_swagger_event_documentation&#039;, &#039;my_plugin_document_suspect_level&#039; );\n\nfunction my_plugin_document_suspect_level( array $documentation ) {\n    $documentation&#x5B;&#039;properties&#039;]&#x5B;&#039;raccoon_suspect_level&#039;] = array(\n        &#039;type&#039;        =&gt; &#039;integer&#039;,\n        &#039;description&#039; =&gt; __( &#039;Suspicion level on a 1 to 5 scale&#039;, &#039;my-plugin&#039; ),\n    );\n    return $documentation;\n}\n<\/pre><\/div>\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/images.theeventscalendar.com\/kb\/uploads\/2017\/09\/racoon-documentation-665x408.png\" alt=\"A custom field documented and visible in the Swagger.io output\"\/><\/figure>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"h-one-click-client-generation\">One-Click Client Generation<\/h4>\n\n\n\n<p>Because the documentation is in Swagger format, you can generate a REST API client in the language of your choice directly from the Swagger.io editor. Copy your <code>\/doc<\/code> endpoint JSON, paste it into the <a href=\"https:\/\/editor.swagger.io\/\">Swagger.io editor<\/a>, then click <strong>Generate Client<\/strong> from the top menu and select your target language.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/images.theeventscalendar.com\/kb\/uploads\/2017\/09\/swagger-io-editor-generate-665x409.png\" alt=\"The Generate Client menu in the Swagger.io editor\"\/><\/figure>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/images.theeventscalendar.com\/kb\/uploads\/2017\/09\/swagger-io-editor-generation-gif.gif\" alt=\"Animation showing client code being generated from the Swagger.io editor\"\/><\/figure>\n\n\n\n<p>You will receive a downloadable archive containing The Events Calendar REST API client code in your selected language.<\/p>\n\n\n\n<p><strong>Note:<\/strong> If the Swagger editor does not work with your endpoint output, installing the <a href=\"https:\/\/wordpress.org\/plugins\/wp-api-swaggerui\/\">WP API SwaggerUI plugin<\/a> may help.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The Events Calendar and Event Tickets include a built-in REST API that lets you read, create, update, and delete event data from outside WordPress \u2014 whether from a mobile app, an external site, a script, or another service. This article covers what a REST API is, how the TEC endpoints are structured, how to make&#8230;<\/p>\n","protected":false},"author":44,"featured_media":1955565,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_kad_blocks_custom_css":"","_kad_blocks_head_custom_js":"","_kad_blocks_body_custom_js":"","_kad_blocks_footer_custom_js":"","_swpsp_post_exclude":false,"_kad_post_transparent":"","_kad_post_title":"","_kad_post_layout":"","_kad_post_sidebar_id":"","_kad_post_content_style":"","_kad_post_vertical_padding":"","_kad_post_feature":"","_kad_post_feature_position":"","_kad_post_header":false,"_kad_post_footer":false,"ep_exclude_from_search":false,"footnotes":""},"categories":[24],"tags":[303],"stellar-product-taxonomy":[155,161],"class_list":["post-1960250","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-customizing","tag-rest-api","stellar-product-taxonomy-event-tickets","stellar-product-taxonomy-the-events-calendar"],"acf":[],"taxonomy_info":{"category":[{"value":24,"label":"Customizations"}],"post_tag":[{"value":303,"label":"Rest API"}],"stellar-product-taxonomy":[{"value":155,"label":"Event Tickets"},{"value":161,"label":"The Events Calendar"}]},"featured_image_src_large":["https:\/\/images.theeventscalendar.com\/kb\/uploads\/2023\/02\/social-share-1024x538.png",1024,538,true],"author_info":{"display_name":"Sam Dokus","author_link":"https:\/\/theeventscalendar.com\/knowledgebase\/author\/sam-dokus\/"},"comment_info":0,"category_info":[{"term_id":24,"name":"Customizations","slug":"customizing","term_group":0,"term_taxonomy_id":24,"taxonomy":"category","description":"","parent":0,"count":76,"filter":"raw","term_order":"0","cat_ID":24,"category_count":76,"category_description":"","cat_name":"Customizations","category_nicename":"customizing","category_parent":0}],"tag_info":[{"term_id":303,"name":"Rest API","slug":"rest-api","term_group":0,"term_taxonomy_id":303,"taxonomy":"post_tag","description":"","parent":0,"count":2,"filter":"raw","term_order":"0"}],"_links":{"self":[{"href":"https:\/\/theeventscalendar.com\/knowledgebase\/wp-json\/wp\/v2\/posts\/1960250","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/theeventscalendar.com\/knowledgebase\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/theeventscalendar.com\/knowledgebase\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/theeventscalendar.com\/knowledgebase\/wp-json\/wp\/v2\/users\/44"}],"replies":[{"embeddable":true,"href":"https:\/\/theeventscalendar.com\/knowledgebase\/wp-json\/wp\/v2\/comments?post=1960250"}],"version-history":[{"count":14,"href":"https:\/\/theeventscalendar.com\/knowledgebase\/wp-json\/wp\/v2\/posts\/1960250\/revisions"}],"predecessor-version":[{"id":1969122,"href":"https:\/\/theeventscalendar.com\/knowledgebase\/wp-json\/wp\/v2\/posts\/1960250\/revisions\/1969122"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/theeventscalendar.com\/knowledgebase\/wp-json\/wp\/v2\/media\/1955565"}],"wp:attachment":[{"href":"https:\/\/theeventscalendar.com\/knowledgebase\/wp-json\/wp\/v2\/media?parent=1960250"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/theeventscalendar.com\/knowledgebase\/wp-json\/wp\/v2\/categories?post=1960250"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/theeventscalendar.com\/knowledgebase\/wp-json\/wp\/v2\/tags?post=1960250"},{"taxonomy":"stellar-product-taxonomy","embeddable":true,"href":"https:\/\/theeventscalendar.com\/knowledgebase\/wp-json\/wp\/v2\/stellar-product-taxonomy?post=1960250"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}