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
GETendpoints 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.Events | Base URL |
|---|---|
| Hi.Events Cloud | https://api.hi.events |
| Self-hosted, all-in-one Docker image | Your app’s URL plus /api, for example https://tickets.example.com/api |
| Self-hosted, separate backend image or manual install | Your 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:
| Parameter | What it does | Default |
|---|---|---|
page | Page number | 1 |
per_page | Results per page, up to 100 | 25 |
sort_by | Field to sort by. The fields you can use are listed in the response’s meta.allowed_sorts | Varies |
sort_direction | asc or desc | Varies |
query | Search 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:
| Status | error_code | Meaning |
|---|---|---|
401 | The key is missing, unknown, expired or revoked | |
403 | API_KEY_READ_ONLY | A read-only key tried to make a change |
403 | API_KEY_NOT_ALLOWED | The endpoint can’t be used with an API key |
403 | READ_ONLY_ROLE | The key’s owner has view-only access to the account |
403 | PERMISSION_REQUIRED | The owner’s role lacks a permission the endpoint needs, such as refunds or financial data |
403 | ACCESS_RESTRICTED | The owner only has access to some organizers or events, and this isn’t one of them |
403 | TWO_FACTOR_SETUP_REQUIRED | The account requires two-factor authentication and the owner hasn’t set it up |
429 | Too 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.
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).