Using the Hi.Events REST API

The Hi.Events API is the same API the web app uses. Integrations sign in with an API key and can read and change events, products, orders, attendees, check-ins and more, with the same access as the person who created the key. This page covers what you need to get started. The full list of endpoints is in the API reference inside Hi.Events.

The API Reference

Open Settings → API keys → API reference in Hi.Events. It lists every endpoint an API key can call, with request and response schemas, and lets you send test requests. It already uses the right base URL for your Hi.Events install, so it’s the easiest place to copy URLs from.

Creating an API Key

Open My Profile from the user menu, click API keys and create a key. You choose:

  • Access: Read and write, to call every endpoint you can, or Read-only, for GET endpoints and exports only. Members with the Viewer role can only create read-only keys
  • Expiration: 7, 30, 60, 90 or 180 days, 1 year, or No expiration. Keys that never expire stay valid until they’re revoked, so only use them on servers you control

The full key, starting hie_, is shown once, when you create it. Hi.Events only stores a hash of it, so copy it somewhere safe straight away. For keys that last longer than two weeks, you’ll get an email a week before the key expires.

A key belongs to you and to the one account you created it in. It has your role, permissions and event access, never more, and changes to your role apply to it straight away. Your email address must be confirmed before you can create one, you confirm your password (or sign in again with single sign-on) as you create it, and you can have up to 25 active keys per account.

A key stops working when you or an account admin revoke it, when it expires, when you’re deactivated on the account, and when your single sign-on changes. Resetting your password through Forgot password, or disconnecting a Google or Microsoft sign-in, deletes your keys in every account you belong to.

Base URL

Where you use Hi.EventsBase URL
Hi.Events Cloudhttps://api.hi.events
Self-hosted, all-in-one Docker imageYour app’s URL plus /api, for example https://tickets.example.com/api
Self-hosted, separate backend image or manual installYour backend’s URL, for example https://api.tickets.example.com

On a self-hosted install, the base URL is whatever VITE_API_URL_CLIENT is set to (see Deploying).

Authentication

Send the key as a bearer token with every request, and ask for JSON:

curl https://api.hi.events/events \
  -H "Authorization: Bearer hie_your_key" \
  -H "Accept: application/json"

That lists the events in the key’s account. To list an event’s attendees:

curl "https://api.hi.events/events/123/attendees?per_page=50" \
  -H "Authorization: Bearer hie_your_key" \
  -H "Accept: application/json"

Endpoints under /public/* (event pages, checkout, ticket lookup) need no key and are marked (public) in the reference.

Some endpoints can’t be used with a key, even a read-and-write one: signing in, your profile and sign-in security, the team, API keys, payouts, card readers, VAT settings and account settings. They need you signed in to Hi.Events, and return 403 with error_code: API_KEY_NOT_ALLOWED if you call them with a key.

Pagination, Sorting and Filtering

List endpoints are paginated and take these query parameters:

ParameterWhat it doesDefault
pagePage number1
per_pageResults per page, up to 10025
sort_byField to sort by. The fields you can use are listed in the response’s meta.allowed_sortsVaries
sort_directionasc or descVaries
querySearch term
filter_fields[field][operator]Filter on a field. The fields you can use are listed in meta.allowed_filter_fields

Filter operators are eq, ne, lt, lte, gt, gte, like, ilike and in (with comma-separated values). Use the value null with eq or ne to match empty fields. For example, to list only active attendees:

curl -G "https://api.hi.events/events/123/attendees" \
  --data-urlencode "filter_fields[status][eq]=ACTIVE" \
  -H "Authorization: Bearer hie_your_key" \
  -H "Accept: application/json"

Results come back in data, with links to the next and previous pages, and meta holding current_page, last_page, per_page and total.

Errors

Errors return JSON with a message. Validation errors (422) also include an errors object keyed by field. Access errors include an error_code. The ones you’re most likely to see with a key:

Statuserror_codeMeaning
401The key is missing, unknown, expired or revoked
403API_KEY_READ_ONLYA read-only key tried to make a change
403API_KEY_NOT_ALLOWEDThe endpoint can’t be used with an API key
403READ_ONLY_ROLEThe key’s owner has view-only access to the account
403PERMISSION_REQUIREDThe owner’s role lacks a permission the endpoint needs, such as refunds or financial data
403ACCESS_RESTRICTEDThe owner only has access to some organizers or events, and this isn’t one of them
403TWO_FACTOR_SETUP_REQUIREDThe account requires two-factor authentication and the owner hasn’t set it up
429Too many requests. Wait for the number of seconds in the Retry-After header

The API reference lists the rest.

Rate Limits

By default, each person can make 180 requests a minute, shared between the web app and all of their API keys. Past that, requests return 429. Self-hosted installs can change the limit with APP_API_RATE_LIMIT_PER_MINUTE.

Webhooks

Rather than polling, you can have Hi.Events send a POST request to your URL when something happens, such as a new order, a cancelled attendee or a check-in. Webhooks are set up per event or per organizer, in Hi.Events (see Webhooks) or through the API. Each request body looks like this:

{
    "event_type": "order.created",
    "event_sent_at": "2026-08-07T10:00:00+00:00",
    "payload": { }
}

payload has the same shape as the matching resource in the API reference: an order for order.* events, an attendee for attendee.*, and so on.

Every request carries a Signature header: a hex HMAC-SHA256 of the raw request body, using your webhook’s signing secret as the key. Check it before trusting a payload. In Node.js:

import crypto from 'node:crypto';
 
const isValid = (rawBody, signature, secret) => {
    const expected = crypto.createHmac('sha256', secret).update(rawBody).digest('hex');
    return signature?.length === expected.length
        && crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
};

Compute the signature from the body exactly as it arrived, before parsing it. Re-encoding parsed JSON can change it. Respond quickly with a 2xx status: Hi.Events waits 3 seconds for a response before treating the delivery as failed.

MCP Server for AI Assistants

Hi.Events runs an MCP server, so Claude, ChatGPT and other AI assistants can work with an account through tools: list events, look up attendees, resend tickets, run reports, set up tickets and so on. Organizers connect it from My Profile → API keys → Connected apps, which shows the URL; the help center has the steps for Claude and ChatGPT.

Where you use Hi.EventsMCP URL
Hi.Events Cloudhttps://api.hi.events/mcp
Self-hostedYour API base URL plus /mcp, for example https://tickets.example.com/api/mcp

If your client asks which transport to use, choose HTTP (sometimes called Streamable HTTP), not SSE or stdio.

Signing In

Claude, ChatGPT, Claude Code and most other MCP clients handle sign-in themselves. Give them the URL and they open a Hi.Events page in the browser, where the person picks Read and write or Read only and confirms their password. Hi.Events then emails them to say an app was connected.

If you’re building your own client, sign-in is standard OAuth 2.1. Clients register themselves (dynamic client registration) and have no client secret, and PKCE is required, with the S256 method only. Calling /mcp without a token returns 401, with a WWW-Authenticate header that points to /.well-known/oauth-protected-resource. That document lists the other endpoints.

Access tokens last an hour and work like API keys (they start hie_ too). Each time a client refreshes, it gets a new refresh token and the old one stops working. A refresh token expires after 90 days without use. If an old refresh token is used again, Hi.Events disconnects the app, because that usually means the token was copied. Clients can revoke their own tokens through the standard revocation endpoint (RFC 7009). A connection is also deleted whenever the person’s API keys would be: when their password is reset, when they’re deactivated, or when their single sign-on changes.

Clients that can’t sign in this way can send an API key instead:

claude mcp add --transport http hi-events https://api.hi.events/mcp \
  --header "Authorization: Bearer hie_your_key"

Leave the header off and Claude Code signs in through the browser instead. In Cursor or VS Code, add a server with this URL in their MCP settings, and add the same Authorization header there if you’re using a key.

Tools

There are 52 tools. Each one either only reads or makes changes, never both, and says which, so clients can treat changes differently, for example by asking you before running one.

AreaTools
Organizers and eventslist_organizers, create_organizer, list_events, get_event, create_event, update_event, set_event_cover_image, set_event_venue, list_venues, update_event_settings, update_event_page_theme, publish_event, unpublish_event
Dateslist_event_dates, add_event_date, generate_event_dates, get_date_generation_status
Ticketslist_tickets, create_ticket, update_ticket, create_addon, list_ticket_categories, create_ticket_category, list_shared_capacities, create_shared_capacity, update_ticket_design
Promo codes and questionslist_promo_codes, create_promo_code, update_promo_code, list_questions, create_question, update_question, delete_question
Lineupget_lineup, list_performer_profiles, add_lineup_performer, add_lineup_space, add_schedule_item
Attendees and orderslist_attendees, get_attendee, add_attendee, check_in_attendee, resend_ticket, list_orders, get_order, resend_order_confirmation
Salesget_event_stats, get_organizer_stats, get_event_report, get_organizer_report
Websitelist_widgets, create_widget

Each tool works by calling the same REST endpoint you would, as the person who connected it. So it has their permissions and event access, can’t see sales figures if they can’t, and goes through the same validation and spam checks. Tools that make changes don’t appear at all for read-only connections, read-only keys, or people who can’t edit.

A few conventions the tools share:

  • Dates you send are local times in the event’s timezone (YYYY-MM-DD HH:MM). Dates returned are ISO 8601, with the event’s UTC offset
  • get_event_stats and get_organizer_stats count days in UTC, because daily sales figures are stored by UTC date. The report tools count days in the event’s or organizer’s own timezone, as the dashboard does
  • Organizer money totals cover one currency at a time and list the others in other_currencies
  • Reports return at most 500 rows and say when rows were left out

As with the REST API, new tools can be added at any time. Renaming or removing a tool, or changing what it takes or returns, is avoided and always called out in the release notes.

What the Tools Leave Out

There are no tools for refunds, cancelling orders, marking orders as paid, payouts, payment or invoicing settings, or messaging attendees. No tool can change an attendee’s or buyer’s email address, so a misled assistant can’t send a ticket somewhere new.

resend_ticket and resend_order_confirmation only email the address already on record, at most once per attendee or order every 10 minutes. Separately, one email address gets at most 5 emails from the tools every 10 minutes, counting add_attendee too.

Rate Limits

You can make 120 requests a minute to /mcp. Within that, each connection or key can make 60 changes a minute. Each change also uses 2 to 4 requests of your normal API rate limit, because the tool makes several API calls to do it. Setting up a full event from nothing takes about 35 changes.

Self-hosting?

The MCP server is part of the backend, with nothing to switch on. If you run your own reverse proxy, it needs to send a few sign-in addresses under /.well-known/ to the backend (see AI Assistants and OAuth Discovery), and the scheduler clears out old tokens and connections.

Stability

The API isn’t versioned yet. The endpoints API keys can call are kept backward compatible: new endpoints, optional request fields and response fields can be added at any time, so ignore fields you don’t recognise. Removing or renaming an endpoint or field, or changing what it means, is avoided where possible and always called out in the release notes.

Self-hosting?

The in-app API reference works with no configuration. To also serve the full generated documentation, including the endpoints only the web app uses, set API_DOCS_ENABLED=true (see Deploying).