Public Events API
The public events API is consumed by embedded widgets and third-party integrations. All endpoints authenticate with a publishable widget key in the X-Widget-Key header (see Widget Keys).
These endpoints only return events with state = published. Draft, archived, and unpublished events return 404 NOT_FOUND.
Get event details
Returns the full public event payload — fields safe for client-side rendering. Excludes precise coordinates and internal IDs.
An event whose registration has not opened, has closed, or is full still returns 200; read registration_open and is_sold_out to decide what to render. The 400 below is only for an event that takes no registrations at all.
Path parameters
- Name
id- Type
- string
- Description
The ULID of the event.
Response shape
Returns the event directly on data. There is no item wrapper on a single resource — only list endpoints use one. ULIDs are 26-character alphanumeric.
Identification
id,title,slug,summary,description(HTML),public_url
Pricing
pricing_model:'free' | 'paid' | 'external'currency: 3-letter ISO 4217 code, uppercase (e.g.'USD')
Date and time
start_date,end_date(YYYY-MM-DD)start_time,end_time(HH:mm:ss)timezone(IANA identifier)start_datetime_utc,end_datetime_utc(ISO 8601)
Location
is_online: booleanvirtual_platform: string whenis_onlineis true, otherwise nulladdress:{ venue_name, city, state, country, display_address }or null. Coordinates are intentionally omitted from the public API.
Registration
has_tickets,requires_registration,requires_approval,registration_open,is_sold_out
Relations
category:{ name, slug }or nullorganization:{ name, slug, logo, is_verified }or nullcover_image:{ url, alt_text }(always present; falls back to a placeholder)ticket_types[]: only types a buyer could take right now. An inactive type, a sold-out one, or one whose sale window has not opened or has already closed is left out (see below)features[]:{ name, slug, category }
Ticket type fields
- Name
id- Type
- string
- Description
- ULID.
- Name
name- Type
- string
- Description
- Display name.
- Name
description- Type
- string?
- Description
- Optional description.
- Name
price_cents- Type
- integer
- Description
- Minor currency units. Zero for free types.
- Name
currency- Type
- string
- Description
- 3-letter ISO 4217 code, uppercase.
- Name
quantity_available- Type
- integer | null
- Description
Seats still available, net of tickets held in other shoppers' live carts. Null when the type is uncapped, which means "no limit" — not "none left". Do not print null as a count and do not read it as sold out; only
max_per_orderbounds an uncapped type.
- Name
max_per_order- Type
- integer
- Description
- Per-order maximum (default 10 if unset).
- Name
min_per_order- Type
- integer
- Description
- Per-order minimum (default 1 if unset).
- Name
is_free- Type
- boolean
- Description
- true when price_cents is zero.
Request
curl https://api.qariyb.com/api/v1/public/events/01HWX9KPQR \
-H "X-Widget-Key: pk_live_..." \
-H "Accept: application/json"
Response
{
"success": true,
"code": 100,
"locale": "en",
"message": "OK",
"data": {
"id": "01HWX9KPQR5T7V8MNCBDJ3GFYZ",
"title": "Community Iftar Dinner",
"slug": "community-iftar-dinner",
"summary": "Join us for a blessed evening...",
"description": "<p>Full description...</p>",
"pricing_model": "paid",
"currency": "GBP",
"start_date": "2026-06-16",
"start_time": "18:30:00",
"end_date": "2026-06-16",
"end_time": "21:00:00",
"timezone": "Europe/London",
"start_datetime_utc": "2026-06-16T17:30:00+00:00",
"end_datetime_utc": "2026-06-16T20:00:00+00:00",
"is_online": false,
"virtual_platform": null,
"address": {
"venue_name": "Al-Noor Islamic Centre",
"city": "London",
"state": null,
"country": "GB",
"display_address": "Al-Noor Islamic Centre, London, GB"
},
"has_tickets": true,
"requires_registration": true,
"requires_approval": false,
"registration_open": true,
"is_sold_out": false,
"category": {
"name": "Ramadan & Eid Events",
"slug": "ramadan-eid-events"
},
"organization": {
"name": "Al-Noor Islamic Centre",
"slug": "al-noor-islamic-centre",
"logo": null,
"is_verified": false
},
"cover_image": {
"url": "https://qariyb.com/storage/events/iftar.jpg",
"alt_text": "Community Iftar Dinner"
},
"ticket_types": [
{
"id": "01HWX9TKT123",
"name": "Individual Ticket",
"description": "Single person ticket",
"price_cents": 1500,
"currency": "GBP",
"quantity_available": 172,
"max_per_order": 8,
"min_per_order": 1,
"is_free": false
}
],
"features": [
{
"name": "Halal Food",
"slug": "halal_food",
"category": "dietary"
}
],
"public_url": "https://qariyb.com/discover/events/community-iftar-dinner"
}
}
List ticket types
Returns just the available ticket types for an event. Useful when the widget already has the rest of the event payload cached.
Returns 400 with EVENT_NOT_AVAILABLE (code: 500) when the event has has_tickets = false.
Response fields
- Name
event_id- Type
- string
- Description
- Event ULID.
- Name
currency- Type
- string
- Description
- Event-level currency, uppercase.
- Name
ticket_types- Type
- TicketType[]
- Description
- Same shape as on the event details endpoint.
- Name
registration_open- Type
- boolean
- Description
- Whether the event is currently accepting registrations.
- Name
is_sold_out- Type
- boolean
- Description
truewhen every ticket type is exhausted, or when the event's own attendee cap has been reached. Counted from tickets sold, so seats merely held in live carts do not count — a type can reportquantity_available: 0while this is stillfalse.
Request
curl https://api.qariyb.com/api/v1/public/events/01HWX9KPQR/tickets \
-H "X-Widget-Key: pk_live_..." \
-H "Accept: application/json"
Response
{
"success": true,
"code": 100,
"locale": "en",
"message": "OK",
"data": {
"event_id": "01HWX9KPQR5T7V8MNCBDJ3GFYZ",
"currency": "GBP",
"ticket_types": [
{
"id": "01HWX9TKT123",
"name": "Individual Ticket",
"description": null,
"price_cents": 1500,
"currency": "GBP",
"quantity_available": 172,
"max_per_order": 8,
"min_per_order": 1,
"is_free": false
}
],
"registration_open": true,
"is_sold_out": false
}
}
Check availability
Lightweight endpoint for widgets to decide whether to render a checkout CTA. Always returns HTTP 200; the body indicates the outcome.
Only available and reason are guaranteed. The remaining fields are populated only on success paths and omitted when reason is 'event_not_found' or 'event_not_available'.
Response fields
- Name
available- Type
- boolean
- Description
true when the event is published, registration is open, and capacity remains.
- Name
reason- Type
- string | null
- Description
One of 'event_not_found', 'event_not_available', 'sold_out', 'registration_closed', or null when the event is available.
- Name
event_id- Type
- string?
- Description
- Event ULID. Present only on success paths.
- Name
registration_open- Type
- boolean?
- Description
- Present only on success paths.
- Name
has_tickets- Type
- boolean?
- Description
- Present only on success paths.
- Name
is_sold_out- Type
- boolean?
- Description
- Present only on success paths.
- Name
total_tickets_available- Type
- integer?
- Description
Sum of what the listed types can still sell, net of seats held in live carts. An uncapped type contributes an internal allowance rather than a real limit, so treat this as a hint rather than a guarantee. Present only on success paths.
Request
curl https://api.qariyb.com/api/v1/public/events/01HWX9KPQR/availability \
-H "X-Widget-Key: pk_live_..." \
-H "Accept: application/json"
Response (available)
{
"success": true,
"code": 100,
"data": {
"available": true,
"reason": null,
"event_id": "01HWX9KPQR5T7V8MNCBDJ3GFYZ",
"registration_open": true,
"has_tickets": true,
"is_sold_out": false,
"total_tickets_available": 172
}
}
Response (event not found)
{
"success": true,
"code": 100,
"data": {
"available": false,
"reason": "event_not_found"
}
}
Errors
| HTTP | ApiCode | Scenario |
|---|---|---|
| 401 | 600 WIDGET_KEY_MISSING | No X-Widget-Key header. |
| 401 | 601 WIDGET_KEY_INVALID | Unknown, inactive, or malformed key. |
| 403 | 604 WIDGET_ORIGIN_DENIED | Origin not in the key's allowed_domains. |
| 404 | 203 NOT_FOUND | Event ULID not found, not published, or belonging to another organization (show and tickets only). |
| 400 | 500 EVENT_NOT_AVAILABLE | On show: the event neither sells tickets nor takes registrations (has_tickets and requires_registration both false). On tickets: has_tickets = false. |
| 429 | 605 WIDGET_RATE_LIMITED | Per-key read limit exceeded. |