EasyEntry Public API
Base URL: https://api.easyentry.com.au. JSON in / JSON out. Auth via X-API-Key (eek_*).
Authentication
Organisation-scoped keys. Published event reads may omit the key; all writes and org-scoped reads require it. Money-moving POSTs also require Idempotency-Key.
X-API-Key: eek_…
Errors
Always {"error": "…", "code": "…"}. Stable codes include invalid_api_key, organisation_suspended, rate_limit_exceeded, idempotency_key_required, unavailable, not_found, invalid_json, invalid_amount, invalid_quantity, too_many_items, charges_not_enabled, registration_invalid, ticket_answers_invalid, ticket_answers_not_supported, refund_rejected.
Endpoints
| Method | Path | Auth |
|---|---|---|
| GET | /v1/events | key/none |
| GET | /v1/events/<org_slug>/<event_slug> | key/none |
| GET | /v1/events/<org_slug>/<event_slug>/availability | key/none |
| GET | /v1/events/<org_slug>/<event_slug>/seats?session=<slug> | key/none |
| GET | /v1/organisers/<slug> | none |
| POST | /v1/holds | key + Idempotency-Key |
| DELETE | /v1/holds/<hold_key> | key |
| POST | /v1/orders | key + Idempotency-Key |
| GET | /v1/orders/<reference> | key |
| POST | /v1/orders/<reference>/refund | key + Idempotency-Key |
| GET | /v1/tickets/<code> | key |
| POST | /v1/checkins | key |
List events
Filters: q (full-text), organiser (org slug), city (or location), and category. Page with after_id (alias after) set to the last event id you received.
GET /v1/events?q=jazz&city=Sydney&after_id=1042
Create order
{
"event": "spring-gala-2026",
"items": [{"ticket_type": "adult", "session": "night-1", "quantity": 2}],
"buyer": {"name": "Jamie Lee", "email": "jamie@example.com"},
"registration": {"dietary": "vegetarian"},
"source": "api"
}
Keys in registration that the event's form doesn't define are ignored.
For per-ticket questions, send ticket_answers: a list with one {"key": "value"} object per ticket issued, in ticket order. Answers come back on each ticket as answers.
Seated events
An event whose seating_mode is reserved (assigned seating) is sold by seat. Read its map with
GET /v1/events/<org_slug>/<event_slug>/seats?session=<slug> (linked as seats_url on the event): each section lists the
ticket type slugs it sells and each seat has an id and a state of available, held, sold or blocked.
Then order by seat:
{
"event": "gala",
"seats": [
{"seat": 412, "session": "night-1", "ticket_type": "adult"},
{"seat": 413, "session": "night-1"}
],
"buyer": {"name": "Jamie Lee", "email": "jamie@example.com"}
}
ticket_type is optional when the seat's section sells one type. Seated events take seats instead of items: the order lines are worked out for you.
The response lists the seats and, while the order is pending, hold_expires_at; issued tickets carry seat_id and seat_label.
Seat errors: 400 invalid_seats, 400 items_not_allowed, 400 seats_not_supported, 409 seats_unavailable (with the seats ids),
and 409 seat_ticket_type. Nothing is reserved when an order is refused.
Holding seats
To keep seats while a buyer fills in their details, POST /v1/holds with {"event": "gala", "seats": [{"seat": 412, "session": "night-1"}]}
and an Idempotency-Key (no ticket type needed). The response has a hold_key, expires_at (10 minutes) and the held seats;
retrying with the same Idempotency-Key returns the same hold and extends it. Pass the hold_key in POST /v1/orders to buy the held seats,
or DELETE /v1/holds/<hold_key> to release them. Unpaid holds expire on their own. An unknown or another organisation's hold_key is 400 invalid_hold on orders and 404 on delete.
Check-in
{"code": "TKT…", "gate": "main"}
Returns result ∈ ok | duplicate | invalid.