Tixdorm API
Power your events with Tixdorm's backend. List events, sell tickets, manage attendees, and accept payments — all through a simple REST API.
Overview
The Tixdorm Partner API lets you build ticketing, registration, and check-in flows directly into your own website or application. You handle the frontend and customer experience; Tixdorm handles the backend — events database, ticket inventory, hosted checkout, QR code generation, email delivery, and real-time attendance tracking.
Common use cases:
- A media site publishing events and selling tickets inline
- A booking platform offering event registration as a service
- A community hub managing member events and check-in
- A festival organizer running multiple events with a unified backend
Multi-tenant by design. Each integration gets its own organization, API keys, webhooks, and data isolation. Your data stays yours.
Base URL
https://api.tixdorm.com/v1
All requests go through api.tixdorm.com. Every response includes CORS headers, so you can call the API directly from the browser.
Authentication
Every request requires a secret API key sent in the Authorization header using the Bearer scheme:
Authorization: Bearer sk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Key types
Each key pair has two components:
- Public Key (
pk_live_xxx) — Identifies your organization. Can be safely exposed. - Secret Key (
sk_live_xxx) — Authenticates all API requests. Keep this server-side.
Environments
- sandboxKeys with
_test_— use for development. No real payments. - productionKeys with
_live_— use for live traffic. Real payments processed.
Security best practices
- Store secret keys in environment variables, never in code or client-side JS
- Rotate keys periodically from the dashboard
- If a key is compromised, revoke it immediately and generate a new one
- Full keys are shown only once at generation time
API Endpoints
Events
/v1/eventsList all published events.
Response
{
"ok": true,
"data": [
{
"id": "uuid",
"title": "Tolu W. Art Exhibition",
"slug": "tolu-w-art-exhibition",
"description": "An evening of contemporary art...",
"location": "Lagos, Nigeria",
"starts_at": "2026-07-01T18:00:00Z",
"ends_at": "2026-07-01T22:00:00Z",
"status": "published",
"capacity": 500,
"event_type": "in_person",
"cover_image_url": "https://...",
"is_paid": true,
"price_cents": 5000,
"currency": "NGN",
"created_at": "2026-06-01T10:00:00Z",
"updated_at": "2026-06-15T12:00:00Z"
}
]
}/v1/events/{event_id}Get a single event by ID, including its ticket tiers.
Response
{
"ok": true,
"data": {
"id": "uuid",
"title": "Tolu W. Art Exhibition",
"ticket_tiers": [
{
"id": "uuid",
"name": "VIP",
"price_cents": 15000,
"quantity": 50,
"sold_count": 12,
"is_active": true
}
]
}
}/v1/eventsCreate a new event under your organization.
Request body
{
"title": "My Event",
"description": "Event details...",
"venue": "Lagos, Nigeria",
"start_date": "2026-07-01T10:00:00Z",
"end_date": "2026-07-01T18:00:00Z",
"capacity": 500,
"event_type": "in_person"
}Response
{
"ok": true,
"data": { "id": "uuid", "title": "My Event", ... }
}/v1/events/{event_id}Update one or more fields on an event you own.
Request body
{
"title": "Updated Title",
"venue": "New Venue, Abuja",
"capacity": 1000,
"event_type": "hybrid"
}Response
{
"ok": true,
"data": { "id": "uuid", "title": "Updated Title", ... }
}Tickets
/v1/events/{event_id}/ticketsList all ticket tiers for an event.
Response
{
"ok": true,
"data": [
{
"id": "uuid",
"name": "General Admission",
"description": "Standard entry",
"price_cents": 5000,
"quantity": 200,
"sold_count": 45,
"is_active": true,
"sales_start": "2026-06-01T00:00:00Z",
"sales_end": "2026-07-01T00:00:00Z"
}
]
}/v1/ticketsCreate a new ticket tier for an event you own. If `price` > 0, online payments are automatically enabled for the event.
Request body
{
"event_id": "evt_uuid",
"name": "VIP Pass",
"description": "Includes meet-and-greet",
"price": 15000,
"quantity": 100,
"sales_start": "2026-06-01T00:00:00Z",
"sales_end": "2026-07-01T00:00:00Z",
"visibility": "public"
}Response
{
"ok": true,
"data": { "id": "uuid", "name": "VIP Pass", ... }
}Checkout
/v1/checkoutCreate a checkout. For paid tiers returns a Flutterwave payment URL; for free tiers returns the ticket token directly.
Request body
{
"event_id": "evt_uuid",
"ticket_id": "tier_uuid",
"quantity": 2,
"customer_name": "John Doe",
"customer_email": "john@example.com",
"customer_phone": "+2348012345678"
}Response
{
"ok": true,
"data": {
"checkout_url": "https://api.flutterwave.com/...",
"tx_ref": "tix_abc_..."
}
}/v1/verify-paymentVerify a Flutterwave payment and retrieve the ticket token after a successful checkout.
Request body
{
"tx_ref": "tix_abc_...",
"transaction_id": "1234567"
}Response
{
"ok": true,
"data": {
"confirmed": true,
"ticket_token": "qr_token_here"
}
}Attendees
/v1/events/{event_id}/attendeesList all ticket purchasers for an event you own.
Response
{
"ok": true,
"data": [
{
"id": "uuid",
"buyer_name": "John Doe",
"buyer_email": "john@example.com",
"buyer_phone": "+2348012345678",
"tier_id": "uuid",
"amount_paid_cents": 5000,
"status": "valid",
"purchased_at": "2026-06-20T14:30:00Z",
"validated_at": null,
"ticket_tiers": { "name": "General Admission" }
}
]
}/v1/attendeesManually register an attendee (comp tickets, guest list).
Request body
{
"event_id": "evt_uuid",
"ticket_id": "tier_uuid",
"name": "Jane Doe",
"email": "jane@example.com",
"phone": "+2348012345678"
}Response
{
"ok": true,
"data": {
"id": "uuid",
"event_id": "evt_uuid",
"buyer_name": "Jane Doe",
"buyer_email": "jane@example.com",
"status": "valid"
}
}Check-In
/v1/checkinValidate a ticket and mark the attendee as checked in.
Request body
{
"ticket_id": "tkt_uuid"
}Response
{
"ok": true,
"data": {
"status": "checked_in",
"timestamp": "2026-06-23T12:00:00Z",
"ticket_id": "tkt_uuid"
}
}QR Codes
/v1/tickets/{ticket_id}/qrRetrieve QR code URL and ticket portal link for a ticket.
Response
{
"ok": true,
"data": {
"qr_url": "https://supabase.co/functions/v1/scan-validate?token=abc...",
"ticket_url": "https://tixdorm.com/t/abc...",
"ticket_id": "tkt_uuid",
"event_id": "evt_uuid"
}
}Broadcast
/v1/events/{event_id}/broadcastSend an email update to all verified attendees of an event.
Request body
{
"subject": "Venue Update",
"message": "The venue has changed to Harbour Point. See you there!"
}Response
{
"ok": true,
"data": {
"sent": 45,
"failed": 0,
"total": 45
}
}Merch — Products
/v1/events/{event_id}/productsList all merch products for an event you own.
Response
{
"ok": true,
"data": [
{
"id": "uuid",
"name": "Festival T-Shirt",
"slug": "festival-t-shirt",
"description": "Premium cotton tee",
"category": "apparel",
"cover_image_url": "https://...",
"price_cents": 5000,
"compare_at_price_cents": 7000,
"status": "active",
"inventory_quantity": 100,
"track_inventory": true,
"has_variants": true,
"units_sold": 23,
"created_at": "2026-06-01T10:00:00Z"
}
]
}/v1/events/{event_id}/productsCreate a new merch product for an event you own.
Request body
{
"name": "Festival T-Shirt",
"description": "Premium cotton tee",
"category": "apparel",
"price_cents": 5000,
"compare_at_price_cents": 7000,
"status": "active",
"inventory_quantity": 100,
"track_inventory": true,
"has_variants": false
}Response
{
"ok": true,
"data": { "id": "uuid", "name": "Festival T-Shirt", ... }
}/v1/products/{product_id}Get a single product by ID, including variants and images.
Response
{
"ok": true,
"data": {
"id": "uuid",
"name": "Festival T-Shirt",
"variants": [
{ "id": "uuid", "name": "Size", "value": "XL", "price_override_cents": null, "inventory_override": null }
],
"images": [
{ "id": "uuid", "url": "https://...", "alt_text": "Front view", "position": 0 }
]
}
}/v1/products/{product_id}Update one or more fields on a product you own.
Request body
{
"name": "Updated T-Shirt",
"price_cents": 6000,
"status": "active"
}Response
{
"ok": true,
"data": { "id": "uuid", "name": "Updated T-Shirt", ... }
}Merch — Orders
/v1/events/{event_id}/ordersList all merch orders for an event you own.
Response
{
"ok": true,
"data": [
{
"id": "uuid",
"customer_name": "John Doe",
"customer_email": "john@example.com",
"customer_phone": "+2348012345678",
"subtotal_cents": 10000,
"delivery_fee_cents": 1500,
"total_cents": 11500,
"currency": "NGN",
"payment_status": "paid",
"fulfilment_status": "unfulfilled",
"flw_tx_ref": "tix_xxx",
"created_at": "2026-06-20T14:30:00Z"
}
]
}/v1/orders/{order_id}Get a single merch order by ID, including items.
Response
{
"ok": true,
"data": {
"id": "uuid",
"customer_name": "John Doe",
"total_cents": 11500,
"payment_status": "paid",
"fulfilment_status": "unfulfilled",
"items": [
{
"id": "uuid",
"product_name": "Festival T-Shirt",
"variant_name": "Size",
"variant_value": "XL",
"quantity": 2,
"unit_price_cents": 5000,
"total_price_cents": 10000,
"fulfilment_method": "delivery"
}
]
}
}Applications
/v1/events/{event_id}/applicationsList all application configs for an event (volunteer, exhibitor, vendor, sponsor, speaker, media).
Response
{
"ok": true,
"data": [
{
"id": "uuid",
"application_type": "exhibitor",
"name": "Exhibitor Applications",
"description": "Apply to showcase at the event",
"is_active": true,
"deadline": "2026-07-15T23:59:59Z",
"max_slots": 50,
"allow_file_uploads": true,
"enable_auto_approval": false,
"created_at": "2026-06-01T10:00:00Z"
}
]
}/v1/events/{event_id}/applicationsCreate an application config for an event you own.
Request body
{
"application_type": "exhibitor",
"name": "Exhibitor Applications",
"description": "Apply to showcase at the event",
"deadline": "2026-07-15T23:59:59Z",
"max_slots": 50,
"allow_file_uploads": true,
"enable_auto_approval": false,
"form_fields": [...],
"is_active": true
}Response
{
"ok": true,
"data": { "id": "uuid", "application_type": "exhibitor", ... }
}/v1/events/{event_id}/applications/{type}Get an application config by type (volunteer, exhibitor, vendor, sponsor, speaker, media, custom).
Response
{
"ok": true,
"data": {
"id": "uuid",
"application_type": "exhibitor",
"name": "Exhibitor Applications",
"description": "Apply to showcase",
"form_fields": [...],
"is_active": true,
"deadline": "2026-07-15T23:59:59Z",
"max_slots": 50,
"allow_file_uploads": true,
"enable_auto_approval": false
}
}/v1/events/{event_id}/applications/{type}Update an application config for an event you own.
Request body
{
"name": "Updated Exhibitor Apps",
"max_slots": 75,
"is_active": true
}Response
{
"ok": true,
"data": { "id": "uuid", "application_type": "exhibitor", ... }
}/v1/events/{event_id}/applications/{type}/submissionsList all submissions for a given application type.
Response
{
"ok": true,
"data": [
{
"id": "uuid",
"first_name": "Jane",
"last_name": "Doe",
"email": "jane@example.com",
"phone": "+2348012345678",
"status": "pending",
"assigned_role": null,
"answers": { "business_name": "Art House", ... },
"created_at": "2026-06-20T14:30:00Z"
}
]
}/v1/events/{event_id}/applications/{type}/submissions/{submission_id}Get a single submission with all details.
Response
{
"ok": true,
"data": {
"id": "uuid",
"first_name": "Jane",
"last_name": "Doe",
"email": "jane@example.com",
"status": "pending",
"answers": { ... },
"files": [...],
"notes": null
}
}/v1/events/{event_id}/applications/{type}/submissions/{submission_id}Update a submission's status (approve, reject, waitlist) or add notes.
Request body
{
"status": "approved",
"assigned_role": "Exhibitor - Art Section",
"notes": "Approved via API"
}Response
{
"ok": true,
"data": { "id": "uuid", "status": "approved", ... }
}Hosted Checkout
The POST /v1/checkout endpoint handles the full purchase flow so you don't need to build a checkout UI.
- Create a checkout — Call
POST /v1/checkoutwith the event, ticket tier, and customer info. - Redirect the buyer — For paid tiers, send the customer to the
checkout_url(a Flutterwave-hosted payment page that supports card, USSD, bank transfer, and mobile money). For free tiers, theticket_tokenandticket_idare returned directly. - The buyer completes payment — On Flutterwave's page, the buyer pays and is redirected back to your site.
- Ticket email is sent — As soon as payment is confirmed, the buyer receives a beautifully designed email with their QR code entry pass and event details.
- Verify payment — Use
POST /v1/verify-paymentwith thetx_refandtransaction_idto confirm payment was successful and get the ticket token.
Webhooks
Supported events
Delivery format
Webhooks are delivered as HTTP POST requests to your configured endpoint URL.
{
"event": "attendee.created",
"timestamp": "2026-06-23T12:00:00Z",
"data": {
"attendee_id": "uuid",
"event_id": "uuid",
"attendee_name": "John Doe",
"attendee_email": "john@example.com"
}
}Headers
Content-Type: application/json
X-Tixdorm-Signature: sha256=abc...
X-Tixdorm-Event: attendee.created
X-Tixdorm-Delivery-Id: uuid
Signature verification
Every webhook includes an HMAC SHA256 signature. Verify it using your webhook secret to confirm the payload came from Tixdorm:
const crypto = require('crypto');
function verifyWebhook(payload, signature, secret) {
const expected = 'sha256=' + crypto
.createHmac('sha256', secret)
.update(JSON.stringify(payload))
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}Retry schedule
If your endpoint doesn't respond with a 2xx status within 5 seconds, Tixdorm retries up to 5 times with exponential backoff: 1 minute → 5 minutes → 30 minutes → 6 hours → 24 hours.
Managing webhooks
Configure webhooks from your Partner API dashboard. You can add multiple endpoints, each with its own signing secret. View delivery logs including status, HTTP response code, and response body for debugging.
Code Examples
Quickstart snippets in popular languages.
# List all events
curl -H "Authorization: Bearer sk_live_xxx" \
https://api.tixdorm.com/v1/events
# Create an event
curl -X POST \
-H "Authorization: Bearer sk_live_xxx" \
-H "Content-Type: application/json" \
-d '{"title":"My Event","start_date":"2026-07-01T10:00:00Z","venue":"Lagos"}' \
https://api.tixdorm.com/v1/events
# Create a ticket tier
curl -X POST \
-H "Authorization: Bearer sk_live_xxx" \
-H "Content-Type: application/json" \
-d '{"event_id":"evt_uuid","name":"VIP","price":15000,"quantity":100}' \
https://api.tixdorm.com/v1/tickets
# Check in an attendee
curl -X POST \
-H "Authorization: Bearer sk_live_xxx" \
-H "Content-Type: application/json" \
-d '{"ticket_id":"tkt_uuid"}' \
https://api.tixdorm.com/v1/checkin
# List merch products
curl -H "Authorization: Bearer sk_live_xxx" \
https://api.tixdorm.com/v1/events/{event_id}/products
# List applications
curl -H "Authorization: Bearer sk_live_xxx" \
https://api.tixdorm.com/v1/events/{event_id}/applications
# List submissions for an application type
curl -H "Authorization: Bearer sk_live_xxx" \
https://api.tixdorm.com/v1/events/{event_id}/applications/exhibitor/submissionsErrors
All errors follow a consistent format:
{
"ok": false,
"error": "A human-readable description of the problem"
}HTTP status codes
Rate Limits
The current rate limit is 100 requests per minute per API key. Exceeding this limit returns a 429 Too Many Requests response.
If your integration requires higher limits, contact support at support@tixdorm.com.
Pricing
Free for all partners
The Partner API is completely free. There are no tiered plans, no monthly fees, and no hidden costs. You only pay the standard 5% platform fee on paid ticket transactions (free events incur no fees).
- ✓ Unlimited events
- ✓ Unlimited tickets
- ✓ Hosted checkout
- ✓ Webhook support
- ✓ Email notifications + QR codes
- ✓ All API endpoints
FAQ
How do I get API access?
Go to your dashboard → Partners → Request Access. An admin will review and approve your request. Once approved, you can generate API keys immediately.
Can I use the API without a hosted checkout page?
Yes. The checkout endpoint is optional. You can create tickets and attendees programmatically using the POST /v1/attendees endpoint.
What happens if my webhook endpoint is down?
Tixdorm retries delivery up to 5 times over 24 hours (1min → 5min → 30min → 6h → 24h). After all attempts fail, the delivery is marked as failed.
Can I have multiple API keys?
Yes. You can generate multiple key pairs for different environments (sandbox vs production) or different applications. Each key pair is independently revocable.
Is my data isolated from other partners?
Yes. Every API key belongs to a single organization. All database queries are scoped to your organization. No cross-tenant data access is possible.
What languages can I use?
Any language that can make HTTP requests. The API is RESTful with JSON request/response bodies.
Support
Need help with the API? Here's how to reach us:
- Email: support@tixdorm.com
- API Status: status.tixdorm.com
