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.

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).