Skip to content

Partner API overview

Sell ShowTix tickets from your own site or app, sync orders to your CRM and scan at the door with the Partner API, webhooks and embeds.

For developersLast updated

On this page

The ShowTix Partner API is a REST API plus signed webhooks for selling your ShowTix events anywhere — your venue site, a festival app, your CRM or your door-scanning setup. It's JSON over HTTPS, money is decimal-dollar strings in AUD, and times are ISO-8601 UTC.

Selling inside a web page and don't want to write server code? Use the embeddable checkout instead — it needs no API key.

curl https://api.showtix-nonprod.link/ \
  -H "Authorization: Bearer $SHOWTIX_API_KEY"

Quickstart#

From zero to a paid order in six steps. Use a test key first — reads return your real data and writes are validated in full but never hold or issue tickets.

  1. Create an API key

    In the dashboard open Developers → API keys → Create key. Choose Test mode and the permissions events:read, orders:read and orders:write. The secret is shown once — store it in your server's environment, never in browser code. Only organisation owners and admins can create keys (who can use Developers).

    bash
    export SHOWTIX_API_KEY="stx_test_..."
  2. List your upcoming events

    GET /events returns your organisation's published, upcoming events, soonest first.

    curl "https://api.showtix-nonprod.link/events?limit=10" \
      -H "Authorization: Bearer $SHOWTIX_API_KEY"
    Response
    {
      "object": "list",
      "data": [
        {
          "object": "event",
          "id": 123,
          "slug": "late-night-cabaret-melbourne",
          "title": "Late Night Cabaret",
          "summary": "Songs, sketches and sequins — a late-night variety bill in Richmond.",
          "description": "Late Night Cabaret returns to the Corner Hotel for one night only. 18+. Doors 7pm.",
          "status": "published",
          "starts_at": "2026-11-02T09:00:00Z",
          "ends_at": "2026-11-02T13:00:00Z",
          "timezone": "Australia/Melbourne",
          "doors": "7:00pm",
          "url": "https://showtix.com.au/shows/late-night-cabaret-melbourne",
          "image_url": "https://showtix.com.au/uploads/events/123/feature.jpg",
          "sold_out": false,
          "on_sale_at": null,
          "venue": {
            "object": "venue",
            "id": 9,
            "name": "Corner Hotel",
            "slug": "corner-hotel",
            "address": {
              "line1": "57 Swan St",
              "line2": null,
              "locality": "Richmond",
              "state": "VIC",
              "postal_code": "3121",
              "country": "AU",
              "formatted": "57 Swan St, Richmond VIC 3121"
            },
            "lat": -37.8253,
            "lng": 144.9932,
            "url": "https://cornerhotel.com",
            "phone": null
          },
          "ticketing": {
            "currency": "AUD",
            "min_price": "49.00",
            "max_price": "89.00",
            "tickets_remaining": 412
          },
          "categories": [
            "cabaret",
            "comedy"
          ],
          "created_at": "2026-09-14T02:31:07Z",
          "updated_at": "2026-10-17T23:12:45Z"
        }
      ],
      "has_more": false,
      "next_cursor": null
    }
  3. List an event's ticket types

    Each ticket type carries its fee-inclusive price, status and live available count. Only on_sale, non-seated types can be sold through a checkout session.

    curl https://api.showtix-nonprod.link/events/123/ticket_types \
      -H "Authorization: Bearer $SHOWTIX_API_KEY"
    Response
    {
      "object": "list",
      "data": [
        {
          "object": "ticket_type",
          "id": 55,
          "pool_id": 31,
          "pool_name": "General Admission",
          "event_id": 123,
          "name": "Early Bird",
          "description": null,
          "price": "49.00",
          "booking_fee": "3.95",
          "currency": "AUD",
          "fees_included": true,
          "gst_applies": true,
          "min_per_order": 1,
          "max_per_order": 10,
          "status": "on_sale",
          "sale_starts_at": null,
          "sale_ends_at": "2026-10-25T13:00:00Z",
          "available": 120,
          "capacity": 500,
          "seated": false
        },
        {
          "object": "ticket_type",
          "id": 56,
          "pool_id": 31,
          "pool_name": "General Admission",
          "event_id": 123,
          "name": "General Admission",
          "description": null,
          "price": "69.00",
          "booking_fee": "4.95",
          "currency": "AUD",
          "fees_included": true,
          "gst_applies": true,
          "min_per_order": 1,
          "max_per_order": 10,
          "status": "not_yet_on_sale",
          "sale_starts_at": "2026-10-25T13:00:00Z",
          "sale_ends_at": null,
          "available": 292,
          "capacity": 500,
          "seated": false
        },
        {
          "object": "ticket_type",
          "id": 57,
          "pool_id": 32,
          "pool_name": "Balcony",
          "event_id": 123,
          "name": "Balcony Reserved",
          "description": "Allocated seating upstairs.",
          "price": "89.00",
          "booking_fee": "5.95",
          "currency": "AUD",
          "fees_included": true,
          "gst_applies": true,
          "min_per_order": 1,
          "max_per_order": 6,
          "status": "on_sale",
          "sale_starts_at": null,
          "sale_ends_at": null,
          "available": 64,
          "capacity": 80,
          "seated": true
        }
      ],
      "has_more": false,
      "next_cursor": null
    }
  4. Create a checkout session

    A checkout session holds the tickets for your customer until expires_at (about 15 minutes) and returns a hosted checkout_url. Send an Idempotency-Key so a retried request never creates a second hold.

    curl https://api.showtix-nonprod.link/checkout_sessions \
      -H "Authorization: Bearer $SHOWTIX_API_KEY" \
      -H "Content-Type: application/json" \
      -H "Idempotency-Key: cart-48211-001" \
      -d '{
        "event_id": 123,
        "items": [{ "ticket_type_id": 55, "quantity": 2 }],
        "customer": { "email": "alex.ng@example.com", "first_name": "Alex", "last_name": "Ng" },
        "metadata": { "crm_contact_id": "cus_48211" }
      }'
    Response · 201
    {
      "object": "checkout_session",
      "id": "f3a9c2d1-7b4e-4e0a-8c56-1d2e3f4a5b6c",
      "status": "open",
      "livemode": true,
      "dry_run": false,
      "event_id": 123,
      "checkout_url": "https://showtix.com.au/checkout/f3a9c2d1-7b4e-4e0a-8c56-1d2e3f4a5b6c",
      "expires_at": "2026-10-18T03:29:00Z",
      "currency": "AUD",
      "subtotal": "98.00",
      "total_fees": "7.90",
      "discount": "0.00",
      "total": "98.00",
      "items": [
        {
          "ticket_type_id": 55,
          "pool_id": 31,
          "name": "Early Bird",
          "quantity": 2,
          "unit_price": "49.00",
          "total": "98.00"
        }
      ],
      "customer": {
        "email": "alex.ng@example.com",
        "first_name": "Alex",
        "last_name": "Ng",
        "phone": null
      },
      "order_id": null,
      "metadata": {
        "crm_contact_id": "cus_48211"
      },
      "created_at": "2026-10-18T03:14:00Z"
    }

    With a test key

    The request is validated exactly as in live mode (scopes, availability, purchase limits, pricing) but nothing is held: the response has "id": null, "dry_run": true, "livemode": false and checkout_url points at the public event page.

  5. Send the customer to checkout_url

    Redirect from your server (or render a link). Payment happens on ShowTix's hosted checkout, so card data never touches your systems. When it completes, the session's status becomes completed and order_id is set.

    Express route
    app.post("/buy", async (req, res) => {
      const session = await createCheckoutSession(req.body); // the call from step 4
      res.redirect(303, session.checkout_url);
    });
  6. Receive order.completed

    In Developers → Webhooks → Add endpoint, enter an HTTPS URL subscribed to order.completed and copy its signing secret. Every delivery is a signed JSON event — verify the ShowTix-Signature header (see verifying signatures), respond 2xx quickly, then fulfil.

    order.completed
    {
      "id": "evt_3kTq9WmZpL2vX8rNa4Hs6dQe",
      "object": "event",
      "type": "order.completed",
      "api_version": "2026-10-18",
      "created": 1792294800,
      "livemode": true,
      "organisation_id": 12,
      "data": {
        "object": {
          "object": "order",
          "id": "f3a9c2d1-7b4e-4e0a-8c56-1d2e3f4a5b6c",
          "event_id": 123,
          "status": "completed",
          "customer": {
            "email": "alex.ng@example.com",
            "first_name": "Alex",
            "last_name": "Ng",
            "phone": null
          },
          "currency": "AUD",
          "subtotal": "98.00",
          "total_fees": "7.90",
          "discount": "0.00",
          "total": "98.00",
          "refunded_amount": "0.00",
          "payment_method": "stripe",
          "checkout_session_id": "f3a9c2d1-7b4e-4e0a-8c56-1d2e3f4a5b6c",
          "sales_channel": "api",
          "channel_origin": null,
          "metadata": {
            "crm_contact_id": "cus_48211"
          },
          "tickets": [
            {
              "object": "ticket",
              "id": 8812,
              "barcode": "5e0c6f2a-91d4-4b8e-a3c1-7f20d9b4c611",
              "order_id": "f3a9c2d1-7b4e-4e0a-8c56-1d2e3f4a5b6c",
              "event_id": 123,
              "ticket_type_id": 55,
              "ticket_type_name": "Early Bird",
              "pool_id": 31,
              "attendee": {
                "first_name": "Alex",
                "last_name": "Ng",
                "email": "alex.ng@example.com"
              },
              "price": "49.00",
              "status": "valid",
              "comp": false,
              "seat_label": null,
              "checked_in_at": null,
              "created_at": "2026-10-18T03:14:22Z",
              "updated_at": "2026-10-18T03:14:22Z"
            }
          ],
          "created_at": "2026-10-18T03:14:00Z",
          "completed_at": "2026-10-18T03:16:41Z",
          "updated_at": "2026-10-18T03:16:41Z"
        }
      }
    }

    Use Send test event on the endpoint to receive a sample payload (livemode: false) while you build — test-key writes never fire webhooks.

Base URLs#

EnvironmentBase URL
Productionhttps://api.showtix.com.au/api/partner/v1
Local developmenthttp://localhost:4020/api/partner/v1

Every path in these docs is relative to the base URL — GET /events means GET https://api.showtix-nonprod.link/events. The API is versioned in the path (/v1) and every response carries ShowTix-Version: 2026-10-18. See the changelog for the versioning policy.

Server-to-server only

API keys are secrets. Requests from a browser are rejected with 403 browser_request_blocked. To sell inside a web page, use the embeddable checkout — it needs no key.

What you can build#

Use caseHowScopes
Venue or presenter websiteRender your What's On listing from /events and /ticket_types; sell with checkout sessions or the embed.events:read · orders:write
Festival or venue appEvent, venue and ticket-type data in-app, hosted checkout in a web view, order.completed to unlock in-app perks.events:read · orders:write · orders:read
CRM / marketing syncBackfill with GET /orders, then stay current with order.* webhooks or updated_since polling. Carry your contact id in metadata.orders:read · webhooks:manage
Door scanningDownload the attendee list before doors, scan with POST /events/{id}/check_ins, listen for ticket.checked_in across devices.attendees:read · check_in:write
Guest listsIssue performer and media comps in bulk with POST /comp_tickets — each guest is emailed their ticket.orders:write
Branded storefrontNo code: claim your own address and theme it — see storefronts.None

Was this article helpful?