# Eventbrite

- Tool: FlutterFlow
- Difficulty: Intermediate
- Time required: 45 minutes
- Last updated: July 2026

## TL;DR

Connect FlutterFlow to Eventbrite by pulling event and ticket data through a Firebase Cloud Function proxy that holds your private API token, then displaying events in a native card list. For ticket purchase, hand off to Eventbrite's hosted checkout URL in a WebView — don't rebuild payments in FlutterFlow. The private token has write access to your Eventbrite organization and must never sit in a FlutterFlow API Call header where it ships in the compiled app.

## List Events Natively, Check Out in WebView — the Right Architecture

Adding Eventbrite to a FlutterFlow app opens up a specific, high-value use case: showing your organization's upcoming events in a native card list inside the app, then sending users to complete ticket purchase on Eventbrite's hosted checkout page. This split architecture is intentional and smart — it avoids rebuilding payment processing (complex, PCI-scope-expanding, risky) while giving users a native browsing experience that feels like a polished product.

The Eventbrite v3 REST API returns all the data you need for a great event listing: event name, description, start and end times, venue, cover image URL, and ticket class details including price ranges and availability. The `/v3/organizations/{id}/events/` endpoint lists all events for your organization, while `/v3/events/{id}/ticket_classes/` gives you the ticket types, costs, and remaining capacity. You can combine these into rich event cards with 'from $X' pricing, 'X tickets left' badges, and 'Sold Out' states — all from a single API.

The critical architecture point: the Eventbrite Private Token (from your account's API Keys page) is the key to your entire Eventbrite organization — it can read all events, attendee lists, and order data, and potentially take actions on your account. Because FlutterFlow compiles to a client-side Flutter app, any token placed in an API Call header ships in the app bundle and is extractable. A Firebase Cloud Function holds the token as a server-side environment variable and proxies requests to Eventbrite. Your FlutterFlow app never sees the raw token — it just calls the function URL and receives clean event JSON in response.

## Before you start

- An Eventbrite account with at least one event created
- Your Eventbrite Private Token from eventbrite.com/account-settings/apps → API Keys
- Your Eventbrite Organization ID (visible in the URL when viewing your organization's events)
- A Firebase project with Cloud Functions enabled (Blaze plan required)
- A FlutterFlow project open in your browser

## Step-by-step guide

### 1. Step 1: Get your Eventbrite API key and organization ID

Log in to Eventbrite and go to eventbrite.com/account-settings/apps. Click 'API Keys' in the sidebar, then 'Create API Key'. Give it a name like 'FlutterFlow App' and click 'Create Key'. On the next screen, copy the 'Private Token' — this is the key you'll use for API calls. It grants access to your organization's events, orders, and attendee data, so treat it like a password.

Your Organization ID is visible in the URL when you navigate to your events page in the Eventbrite dashboard. Open Eventbrite, click on your organization name, and look at the browser URL — it will contain something like `eventbrite.com/organizations/123456789/events`. The number is your Organization ID. You can also get it programmatically from the API by calling `GET /v3/users/me/organizations/` with your private token, which returns a list of organizations with their IDs.

Do not test this token directly in a browser URL (which logs it in history) or paste it into FlutterFlow's API Calls panel. Your next step is to put it safely into a Firebase Cloud Function environment variable.

**Expected result:** You have your Eventbrite Private Token and Organization ID copied and ready to set as Firebase Functions config variables.

### 2. Step 2: Deploy a Firebase Cloud Function proxy for the Eventbrite API

Your Cloud Function holds the private token and acts as the secure gateway between FlutterFlow and the Eventbrite API. In your Firebase project, navigate to the functions/ directory. In `functions/index.js`, write an HTTP-triggered function that accepts a request from FlutterFlow, adds the Authorization header with your private token, calls the appropriate Eventbrite endpoint, and returns the response.

Set your credentials as Firebase Functions config variables (never in source code): run `firebase functions:config:set eventbrite.token="your-private-token" eventbrite.org_id="your-org-id"` in the Firebase CLI, then deploy with `firebase deploy --only functions`.

The proxy function should handle at minimum two calls: listing organization events (`GET /v3/organizations/{orgId}/events/?status=live&expand=venue`) and fetching ticket classes for a specific event (`GET /v3/events/{eventId}/ticket_classes/`). Structure these as separate route branches based on a query parameter, or deploy two separate functions. The proxy also adds CORS headers so FlutterFlow's Test Mode (which runs in a browser) can call it successfully.

```
// Firebase Cloud Function — Eventbrite API proxy
// functions/index.js
const functions = require('firebase-functions');
const https = require('https');

function callEventbrite(path, token) {
  return new Promise((resolve, reject) => {
    const options = {
      hostname: 'www.eventbriteapi.com',
      path: `/v3${path}`,
      method: 'GET',
      headers: {
        'Authorization': `Bearer ${token}`,
        'Content-Type': 'application/json'
      }
    };
    const req = https.request(options, (res) => {
      let data = '';
      res.on('data', chunk => { data += chunk; });
      res.on('end', () => resolve({ status: res.statusCode, body: JSON.parse(data) }));
    });
    req.on('error', reject);
    req.end();
  });
}

exports.eventbriteProxy = functions.https.onRequest(async (req, res) => {
  res.set('Access-Control-Allow-Origin', '*');
  res.set('Access-Control-Allow-Methods', 'GET, OPTIONS');
  res.set('Access-Control-Allow-Headers', 'Content-Type');
  if (req.method === 'OPTIONS') { res.status(204).send(''); return; }

  const token = functions.config().eventbrite.token;
  const orgId = functions.config().eventbrite.org_id;
  const action = req.query.action || 'events';
  const eventId = req.query.eventId || '';

  try {
    let result;
    if (action === 'events') {
      result = await callEventbrite(
        `/organizations/${orgId}/events/?status=live&expand=venue&page_size=50`,
        token
      );
    } else if (action === 'tickets' && eventId) {
      result = await callEventbrite(`/events/${eventId}/ticket_classes/`, token);
    } else {
      res.status(400).json({ error: 'Invalid action' }); return;
    }
    res.status(result.status).json(result.body);
  } catch (err) {
    res.status(500).json({ error: err.message });
  }
});
```

**Expected result:** A deployed Cloud Function that returns live Eventbrite events JSON when called with `?action=events`, and ticket classes when called with `?action=tickets&eventId=YOUR_EVENT_ID`.

### 3. Step 3: Create a FlutterFlow API Group and define the event card data structure

In FlutterFlow, click 'API Calls' in the left navigation panel. Click '+ Add' → 'Create API Group'. Name it 'Eventbrite'. Set the Base URL to your Cloud Function's HTTPS trigger URL. No group-level headers needed — the function handles all Eventbrite auth.

Add an API Call named 'Get Events'. Set Method to GET. In the Variables tab, add a variable `action` with a default value of `events`. In the URL field, append `?action={{ action }}`. Click 'Response & Test' and paste a sample Eventbrite events response. Click 'Generate JSON Paths' — key paths include `$.events[*].id`, `$.events[*].name.text`, `$.events[*].start.local`, `$.events[*].end.local`, `$.events[*].url`, `$.events[*].venue.name`, `$.events[*].venue.address.localized_address_display`.

Add a second API Call named 'Get Ticket Classes'. Set Method to GET. Add variables `action` (default: 'tickets') and `eventId`. URL: `?action={{ action }}&eventId={{ eventId }}`. Test with a real event ID.

Now create the data structure. Go to Settings → Data Types → + Add Data Type. Name it 'EventbriteEvent'. Add fields: `id` (String), `name` (String), `startTime` (String), `venueName` (String), `venueAddress` (String), `checkoutUrl` (String), `status` (String). Create a second Data Type 'TicketClass' with fields: `name` (String), `price` (String), `available` (Integer), `isFree` (Boolean).

**Expected result:** Two API Calls (Get Events and Get Ticket Classes) appear in the Eventbrite group, both returning 200 with event data. EventbriteEvent and TicketClass Custom Data Types are created.

### 4. Step 4: Build the event card list with pricing and availability badges

Open your events screen in FlutterFlow. Add a ListView widget. In the Backend Query panel, set the query to 'API Call' → 'Get Events'. Map the JSON paths to your EventbriteEvent Data Type fields.

For each list item, create an event card. Add a Card widget as the list item container. Inside the card, add a Stack widget to allow a badge overlay. At the bottom of the stack, add a Column with: an Image widget (bound to `$.events[*].logo.url` or a placeholder if null), a Text widget for the event name (bound to `name`), a Row with a calendar icon and a Text widget for the date (bound to `startTime`, formatted to human-readable), and a Row with a location icon and the venue name.

For ticket price display: wire the card's On Visible event to trigger the 'Get Ticket Classes' API Call with the current event's ID. In the ticket classes response, find the minimum `cost.major_value` across all ticket classes and display 'From $X' in a price badge. Handle edge cases: if `is_free` is true on all ticket classes, show 'Free'. If `quantity_sold >= quantity_total` on all classes, show a 'Sold Out' badge with conditional visibility. Use FlutterFlow's conditional visibility feature on the badge Text widget — set it visible only when `quantitySold >= quantityTotal`.

For the checkout hand-off: add a 'Get Tickets' button at the bottom of each card. On the button's On Tap action, use Action Flow Editor → Add Action → Utilities → Launch URL. Set the URL to the current event's `checkoutUrl` field. On mobile, this opens in the device browser. If you prefer in-app, navigate to a separate screen with a WebView widget bound to the event URL — but the external browser approach is recommended to avoid iframe blocking issues.

**Expected result:** A scrollable event card list showing event names, dates, venues, and pricing. Free events show a 'Free' badge, sold-out events show 'Sold Out', and paid events show 'From $X'. Tapping 'Get Tickets' opens the Eventbrite checkout.

### 5. Step 5: Handle availability edge cases and webhook-based updates

Eventbrite ticket availability changes in real time as people purchase tickets — a sold-out event can appear to have tickets in your cached data if you don't refresh. Build in two mechanisms to keep availability accurate.

First, add a pull-to-refresh on the event list: enable the ListView's 'Pull to Refresh' setting and set its action to 'Re-trigger Backend Query'. This gives users a manual refresh mechanism. Second, refresh ticket class availability each time a user opens an event detail screen — execute the 'Get Ticket Classes' API Call on page load, not just when the parent list loaded. This ensures the 'Sold Out' badge reflects the current state before the user tries to buy.

For real-time sold-out updates (premium feature): Eventbrite's webhook system can send a POST request to your Cloud Function endpoint when ticket inventory changes (event `ticket_class.updated`). Add a separate Cloud Function handler that receives these webhooks, checks if any ticket classes are now sold out, and writes the event's sold-out status to a Firestore document. Your FlutterFlow app subscribes to this Firestore document via FlutterFlow's native Firebase integration and updates the 'Sold Out' badge in real time. This is the proper real-time architecture — Eventbrite webhooks → Cloud Function → Firestore → FlutterFlow real-time listener.

Note that private events (with a restricted audience) may return empty ticket data even with valid API credentials if your private token lacks organizer scope for that event. Verify the event's privacy settings in your Eventbrite dashboard if you see empty ticket_classes responses for specific events.

**Expected result:** The event list refreshes on pull. Opening an event detail page triggers a fresh ticket availability check. The 'Sold Out' badge reflects current inventory from the most recent API call.

## Best practices

- Never put the Eventbrite Private Token in a FlutterFlow API Call header — it grants read/write access to your organization's account and ships in the compiled app bundle. Always proxy it through a Cloud Function.
- Hand off ticket purchase to Eventbrite's hosted checkout URL rather than rebuilding payment processing in FlutterFlow — this keeps PCI compliance and payment security on Eventbrite's infrastructure.
- Handle all three ticket states explicitly in the UI: paid (show price), free (show 'Free Register'), and sold out (show greyed 'Sold Out' badge) — missing any state creates a confusing user experience.
- Use `?expand=venue` in the events list call to include venue details in a single request rather than making a separate venue API call per event.
- Refresh ticket availability on the event detail screen load, not just when the parent list loaded — availability changes in real time and a sold-out badge should reflect current state.
- Add pull-to-refresh to the events list so users can check for new events or updated availability without restarting the app.
- For events with multiple ticket tiers, display the minimum price ('From $X') in the list card and show the full tier breakdown on the detail screen — avoid overwhelming the list with pricing details.

## Use cases

### Community events app for a membership organization

A membership organization app that shows its upcoming events — conferences, workshops, networking nights — as a native scrollable card list. Each card shows the event name, date, venue, and a price-from indicator. Tapping a card opens the event detail screen, and tapping 'Get Tickets' opens Eventbrite's hosted checkout in a WebView.

Prompt example:

```
Build an Events screen that shows upcoming events from my Eventbrite organization as card items with event name, date, venue, and a 'Get Tickets' button that opens the Eventbrite checkout link.
```

### Fitness studio class booking companion app

A fitness studio's companion app that shows its weekly class schedule pulled from Eventbrite. Each class card shows the instructor, capacity remaining ('3 spots left'), and price. Free classes show a 'Register Free' button that opens Eventbrite's registration page; paid classes show the price and open the checkout page.

Prompt example:

```
Create a class schedule screen that displays this week's fitness classes from Eventbrite with class name, instructor, time, spots remaining, and a register/buy button per class.
```

### Conference app with agenda and ticket availability

A conference organizer's native app showing the event agenda and ticket tiers. The app fetches ticket classes from Eventbrite — Early Bird, General Admission, VIP — and displays current availability and pricing. Sold-out tiers show a greyed-out 'Sold Out' badge. The purchase flow hands off to Eventbrite's checkout.

Prompt example:

```
Build a ticket pricing screen that shows available ticket tiers for my conference with price, description, and availability, with a 'Buy Now' button that opens the Eventbrite checkout for the selected tier.
```

## Troubleshooting

### 401 Unauthorized when calling the Cloud Function — Eventbrite returns authentication error

Cause: The private token stored in Firebase Functions config is missing, expired, or incorrect. Eventbrite private tokens don't expire automatically but may be revoked if the API key is deleted from the Eventbrite dashboard.

Solution: Run `firebase functions:config:get` to verify the token is present. Go to eventbrite.com/account-settings/apps → API Keys to confirm the key is still active. If the key was deleted or regenerated, update the config: `firebase functions:config:set eventbrite.token="new-token"` and redeploy the function.

### Empty events array even though events exist in the Eventbrite dashboard

Cause: The organization ID in the Cloud Function config is wrong, or the events are not in 'live' status (they may be drafts, ended, or in a different status like 'completed').

Solution: Verify your Organization ID by calling `GET /v3/users/me/organizations/` with your private token (test in a browser or Postman with the token as a Bearer header). Update the function config if the ID is wrong. Try removing the `?status=live` filter temporarily to see all events — if past events appear, adjust the status filter.

### XMLHttpRequest error in FlutterFlow Test Mode — API call blocked in the browser

Cause: The Cloud Function is not returning CORS headers. Browsers (including FlutterFlow's Test Mode) enforce CORS on all cross-origin requests; native iOS/Android builds are not affected.

Solution: Ensure your Cloud Function includes `res.set('Access-Control-Allow-Origin', '*')` and handles OPTIONS preflight by returning 204. The example code in Step 2 includes this. Redeploy the function after adding CORS headers.

### Ticket classes return empty or missing price data for some events

Cause: The event has private ticket classes (not visible without a special access code), or the event uses free registration with no ticket class pricing configured, or the ticket classes are set to 'hidden' in the Eventbrite dashboard.

Solution: Check the event's ticket settings in the Eventbrite dashboard — verify ticket classes are set to 'visible' and have pricing configured. For free events, check the `is_free` flag in the ticket class response and handle it explicitly in the UI (show 'Free' rather than '$0.00'). For private tickets requiring an access code, the FlutterFlow app cannot display those without implementing access code validation.

## Frequently asked questions

### Can I rebuild the ticket checkout inside FlutterFlow instead of using a WebView?

Technically possible but strongly not recommended. Rebuilding a ticketing checkout means handling payment card fields, PCI compliance, order creation via the Eventbrite API, error handling for failed payments, and sending confirmation emails. All of this is already handled by Eventbrite's hosted checkout page. Using a WebView hands off all of this complexity to Eventbrite and keeps your app outside of PCI scope entirely. The WebView approach takes 5 minutes; rebuilding checkout would take weeks and introduces significant risk.

### Does Eventbrite's free plan support API access?

Yes — creating an Eventbrite API key and calling the REST API is free. Eventbrite's paid plans add features like advanced analytics, custom questions, and priority support, but the basic API access for listing events and ticket classes is available at no cost. Check Eventbrite's current documentation for the latest rate limits on API calls.

### Can FlutterFlow receive webhook notifications when a ticket is purchased?

Not directly — FlutterFlow cannot receive inbound HTTP calls. Eventbrite webhooks must be pointed at a Firebase Cloud Function endpoint. The function receives the webhook (order.placed, attendee.created, etc.), processes it, and writes the result to Firestore. Your FlutterFlow app then reads from Firestore in real time using FlutterFlow's native Firebase integration. This is the standard webhook architecture for FlutterFlow: external service → Cloud Function → Firestore → FlutterFlow.

### How do I display events from multiple Eventbrite organizations in one app?

Extend the Cloud Function to accept multiple organization IDs as an array, make parallel API calls to each organization's events endpoint, merge the results, and return a unified event array sorted by start time. Alternatively, create separate API Calls in FlutterFlow for each organization and merge the results in a Custom Function using Dart. Store the organization IDs in Firestore so they can be updated without a code change.

---

Source: https://www.rapidevelopers.com/flutterflow-integrations/eventbrite
© RapidDev — https://www.rapidevelopers.com/flutterflow-integrations/eventbrite
