Overview
This guide shows you how to connect Eventbrite to your Mighty Network with a small backend service that listens for Eventbrite webhooks and calls the Mighty API. When you finish, your integration will:- Invite ticket buyers to a Space. Each attendee on a new Eventbrite order gets an invite to a Space you choose, such as a private Space for event attendees.
- Mirror events. When you publish or update an event on Eventbrite, a matching event appears in a Space in your Network, linked back to the Eventbrite ticket page.
Before you begin
You need:- A Mighty Network on the Scale plan or above, and a Host account on it. OAuth applications are only available on those plans.
- An Eventbrite account that owns the events, and an Eventbrite private token (in Eventbrite, go to Account Settings > Developer Links > API Keys).
- A server that can receive HTTPS requests from Eventbrite and store secrets securely.
Step 1: Create a Mighty OAuth application
1
Create the application
In your Mighty Network, go to Network Admin > Integrations > OAuth Applications and click New OAuth Application. Choose the Confidential client type, because the integration runs on your server and can keep a Client Secret. See OAuth Applications for every setting.
2
Register a redirect URI
Add a redirect URI on your service, for example
https://integrations.example.com/mighty/callback. Your service handles this URI once, when a Host connects the integration.3
Select scopes
Select only the scopes the integration needs:
If you only want to invite ticket buyers, skip
host:write:network_events. Listing Spaces to find your target Space (Step 4) doesn’t require its own scope today.Step 2: Connect the integration as a Host
Your service needs an access token that acts as a Host of the Network. Run the Authorization Code flow once:- A Host visits a “Connect Mighty” page on your service, which redirects them to
https://YOUR-SUBDOMAIN.mn.co/oauth/authorizewith your Client ID, redirect URI, scopes,state, and a PKCE challenge. - The Host approves the scopes and Mighty redirects back to your redirect URI with a
code. - Your service checks
state, exchanges the code at/oauth/token, and stores theaccess_tokenandrefresh_token.
Node.js
Step 3: Add a Mighty API helper
Every Mighty API call is aPOST to your Network’s GraphQL endpoint. Send a User-Agent header, because requests without one are blocked. Check the errors array on every response, because GraphQL returns HTTP 200 for most errors.
Node.js
Step 4: Find your target Space
Invites and events both need the ID of a Space. List your Spaces once and save the ID of the one you want in your service’s configuration:Step 5: Register Eventbrite webhooks
In Eventbrite, go to Account Settings > Developer Links > Webhooks and click Add Webhook. Point it at an endpoint on your service and select these actions:
Eventbrite doesn’t sign webhook requests. Protect your endpoint by:
- Including a long random secret in the webhook URL, such as
https://integrations.example.com/eventbrite/webhook/3f9c…, and rejecting requests that don’t match it. - Treating the request body only as a notification. Fetch the order or event yourself from the
api_urlin the payload, and only after you confirm the URL starts withhttps://www.eventbriteapi.com/.
200 quickly, and do the slow Mighty and Eventbrite calls in a worker, so they don’t hold up the response. Put the webhook on a durable job queue, such as a database-backed queue, and wait for the enqueue to succeed before you respond. Once you return 200, Eventbrite won’t send that webhook again. If “in the background” means an in-process task and your service crashes after responding, the event is lost.
Node.js
Step 6: Invite ticket buyers to a Space
When anorder.placed webhook arrives, fetch the order with its attendees, then send the attendees to createInvites with your Space ID, in batches of 10 or fewer recipients so each call stays in sync mode (see below):
Node.js
createInvites treats each attendee like this:
- New to your Network: they receive an invite email. Accepting it adds them to the Network and the Space.
- Already a member of the Network, but not the Space: they receive an invite to the Space.
- Already in the Space, or already holding a pending invite: they’re skipped and listed in
ignoredRecipients. Replaying the same webhook doesn’t send duplicate invites.
createInvitessends real invite emails. Test against a Space you own before you point the integration at a live event.- The
messagefield can’t contain links. If it does, the mutation returns an error. - Keep each call at 10 or fewer email recipients. Above that,
createInvitesswitches to async mode: it returns immediately withmode: "async"andcountset to the number of recipients you submitted, not the number actually invited.ignoredRecipientsis always empty in async mode, and invalid addresses are dropped silently instead of returned as an error, so you can’t tell from the response who was skipped. The sample code above chunks each order into batches ofMAX_SYNC_RECIPIENTSfor this reason. - In sync mode (10 or fewer recipients), if any recipient’s email fails Mighty’s validation,
createInvitesrejects the whole batch (count: 0) and lists the addresses inerrorsasInvalid Emails: .... The sample code retries once with those addresses removed so the rest of the attendees still get invited. This rejection and retry only happen in sync mode. - Each
createInvitescall creates an invite batch, and a sender is limited to 30 batches an hour and 200 a day; past that, the mutation returns the errorYou are sending too many invites. The sample code’s one call per order, chunked to 10 or fewer recipients, comfortably fits both limits for most events. For an unusually high-volume launch, queue attendees from multiple orders and flush them together — still 10 or fewer recipients per call — to use fewer batches. - To grant access to a paid offering instead of a free Space, pass
planIdandlinkDestinationin place ofspaceId. SeeCreateInvitesInputin the GraphQL Schema Explorer.
Step 7: Mirror Eventbrite events in your Network
When anevent.published or event.updated webhook arrives, fetch the event and pass along config.action from the webhook payload. Only event.published creates a new mirrored event; event.updated only updates one that already exists. Link mirrored events to the Eventbrite page so members buy tickets there.
Node.js
- Store the mapping from Eventbrite event ID to Mighty event ID. Without it, a repeated
event.publishedwebhook creates a duplicate event, and anevent.updatedwebhook is skipped instead of updating anything. - Claim the mapping atomically before you call
createEvent, as the sample code does. Checking for a mapping and saving it afterward isn’t enough: two workers handling duplicate deliveries can both find no mapping and each create an event. - A claim that still has no Mighty event ID after a few minutes means a worker stopped between
createEventand saving the ID, or a request timed out after Mighty created the event. Check the Space for the event before you clear the claim, so a retry doesn’t create a second one. - An event must start in the future. Past Eventbrite events return the error
Start cannot be too soon or in the past. - Events that use the Mighty Zoom integration can’t be created through the Mighty API. Use
online_meetingwith the Eventbrite link, as above. - By default, a new event is also posted to the Space’s feed. Pass
postInFeed: falseto turn that off.
Test the integration
- Create a test event on Eventbrite with a free ticket, and point the integration at a test Space.
- Publish the event. Confirm a matching event appears in the test Space with a link to Eventbrite.
- Register for the event with an email address you control. Confirm the invite email arrives and that accepting it adds you to the Space.
- Place a second order with the same email. Confirm your logs show the address in
ignoredRecipientsand no second email arrives.
Troubleshooting
I get an HTML 403 page instead of JSON
I get an HTML 403 page instead of JSON
Add a non-empty
User-Agent header to every request to api.mn.co. Requests without one are blocked by bot protection.Mutations return FORBIDDEN
Mutations return FORBIDDEN
The token must belong to a Host of the Network and include the scopes from Step 1. If you added a scope to the application after the Host connected, have the Host connect the integration again so the new scope is granted.
Token refresh fails with invalid_grant
Token refresh fails with invalid_grant
The refresh token was already used, revoked, or expired. This often means two refreshes ran at the same time. Serialize refreshes, and have the Host connect the integration again to get a new token pair.
An attendee never got an invite
An attendee never got an invite
Check
ignoredRecipients in your logs first. The attendee may already be in the Space or have a pending invite — but ignoredRecipients is only populated in sync mode (10 or fewer recipients); it’s always empty for an async call. If errors listed Invalid Emails, that address failed Mighty’s email validation (not just a formatting check) and, because the call ran synchronously, the whole batch was rejected with count: 0. The sample code retries once without the listed addresses, so other attendees on the order still get invited, but the attendee with the invalid address never will until they update it on Eventbrite. In async mode, invalid addresses are dropped silently instead, with no error to catch — another reason to keep calls at 10 or fewer recipients.Mirrored events appear twice
Mirrored events appear twice
Your service created a new event instead of updating the existing one. Check that you claim the Eventbrite event ID with a unique key before calling
createEvent, save the Mighty event ID after it succeeds, and look up the mapping before creating.Next steps
Authentication
Token exchange, refresh, and revocation in detail
GraphQL Schema Explorer
Browse
createInvites, createEvent, and every other mutationOAuth Client Architectures
Keep tokens safe in a backend service
Changelog
Track changes to the Mighty API