REST API

Tickets

List, create, update, check in, void, and bulk-operate on tickets. The most-trafficked endpoint for reporting and on-site operations.

A ticket is the durable artifact of a guest’s registration to an event. It carries the barcode, attendee details, custom field answers, scan/check-in state, and links to the underlying line item and order.

Default response fields

Unless ?fields= is specified:

id, kind, created_at, updated_at, number, status, name, email, barcode_id, barcode, note, event_id, ticket_type_id, event_ticket_type_id, list_id, contact_id, sent_at, dispatched_at, downloaded_at, registered_at, checkin_at, expires_at, source_type, source_id.

sent_at is when the ticket was last emailed to the attendee, or null if it never was. dispatched_at carries the same value and is kept only for existing integrations; use sent_at.

source_type is one of line_item (purchased), rsvp (registered to a free event), or invite (issued via guest list). source_id points at the corresponding record.

Relationships (contact, line_item, event_ticket_type, custom_fields, scans, emails, related_emails, sessions, sent_transfers, received_transfer, links, transfer_link, registration_link, photo) are returned only when listed in ?include=.

List tickets

GET /tickets

List tickets

curl -X GET \
  'https://app.guestmanager.com/api/public/v2/tickets?page[cursor]=&page[size]=50' \
  -H 'Authorization: Token abcdefg' \
  -H 'Content-Type: application/json'

List checked-in tickets for specific events

curl -X GET \
  'https://app.guestmanager.com/api/public/v2/tickets?filter[event_ids]=12345&filter[status]=checked_in&include=contact,scans&sort[checkin_at]=desc' \
  -H 'Authorization: Token abcdefg' \
  -H 'Content-Type: application/json'

Request parameters

Parameter Type Description
page[cursor] string Opaque cursor token. Send empty for first page. See Pagination.
page[size] integer Records per page. Default 10, maximum 100.
sort[{field}] string Sort by id, created_at, updated_at, checkin_at, downloaded_at, sent_at. Value is asc or desc.
fields string Comma separated list of fields to return.
include string Comma separated relationships. See Relationships.
filter[id] string Comma separated ticket IDs.
filter[search] string Full-text search across attendee name, email, barcode, and order number. Routes through Elasticsearch when available.
filter[status] string Comma separated statuses: confirmed, checked_in, checked_out, voided, transferred, pending. See Status filter.
filter[event_ids] string Comma separated event IDs.
filter[list_ids] string Comma separated list IDs.
filter[ticket_type_ids] string Comma separated ticket type IDs.
filter[kind] string ticket or pass.
filter[archived] boolean true returns only archived tickets, false excludes them.
filter[photo] boolean true returns only tickets with an uploaded photo (e.g., for check-in identity verification), false only tickets without one.
filter[sent] boolean true returns only tickets that have been emailed (sent_at is set), false only tickets that haven’t.
filter[expired] boolean true returns only tickets past their expires_at, false only tickets still valid or with no expiry.
filter[deleted] boolean true returns only deleted tickets. Omit (or false) to exclude them. Useful for mirroring deletions on an updated_at cursor.
filter[created_at][from] date Tickets created on or after this date.
filter[created_at][to] date Tickets created on or before this date. A date with no time covers that whole day.

Status filter

Value Meaning
confirmed Valid and not checked in yet. Most tickets are in this state until scanned.
checked_in Currently checked in (most recent scan was a check-in).
checked_out Was checked in, then checked out.
voided Voided. The barcode is rejected at check-in.
transferred Handed to someone else. The recipient holds a new ticket; see Ticket transfers.
pending Created for an order that hasn’t been confirmed yet. It has no usable barcode.

Whether a ticket has been emailed or has expired is not a status. Use filter[sent] and filter[expired] for those.

Relationships

Relationship Notes
contact The attendee’s contact record.
line_item The order line item that produced this ticket (when purchased).
line_item.order A brief view of the order behind the line item — id, number, and total. The number matches what merchants see in the Shopify admin (e.g. 1004) for Shopify-sourced orders.
event_ticket_type The ticket-type-on-event link, including PDF/wallet template config.
event_ticket_type.event Above plus the event with venue.
event_ticket_type.ticket_type Above plus the underlying ticket type config.
custom_fields Form responses captured against this ticket.
scans Check-in / check-out history for this ticket. Same records as Arrivals, which can be filtered and paged on their own.
sessions Sub-tickets when the ticket is a parent (e.g., a multi-session pass).
sessions.scans Scans of each session ticket — useful for multi-day pass dashboards.
emails Delivery history (sent emails for this ticket).
related_emails Every email that carried this ticket, including order-level receipts that listed it. Detail views only: it is one query per ticket.
sent_transfers Transfers started from this ticket, newest last. See Ticket transfers.
sent_transfers.recipient Above plus the recipient contact on each transfer.
received_transfer The accepted transfer that issued this ticket, or null if it was not created by a transfer.
received_transfer.recipient Above plus the recipient contact (this ticket’s holder at the time of the transfer).
links Includes pdf, wallet and google_wallet download URLs in the response.
transfer_link { url, blocked_reason }: the URL that starts a transfer of this ticket, or why there is none. See Ticket transfers.
registration_link The buyer-facing page that completes this ticket’s registration.
photo Includes a transformed photo URL (use images[ticket][photo]=...).

Ticket transfers

A transfer hands a ticket to another person. The recipient accepts by email; on acceptance the app issues them a new ticket and the original changes to transferred. Transfers are only reachable through a ticket, via sent_transfers (the ticket is the source) and received_transfer (the ticket was issued by the transfer).

A transferred ticket with its history and the link state

curl -X GET \
  'https://app.guestmanager.com/api/public/v2/tickets/8472134?include=sent_transfers.recipient,received_transfer,transfer_link' \
  -H 'Authorization: Token abcdefg' \
  -H 'Content-Type: application/json'
{
  "id": 8472134,
  "status": "transferred",
  "sent_transfers": [
    {
      "id": 651630,
      "status": "accepted",
      "origin": "manual",
      "created_at": "2026-09-04T10:40:30Z",
      "updated_at": "2026-09-04T10:41:33Z",
      "ticket_id": 8472134,
      "replacement_ticket_id": 8472190,
      "recipient_id": 9921,
      "recipient_name": "Bizzy Bone",
      "sender_id": 9880,
      "recipient": { "id": 9921, "name": "Bizzy Bone", "email": "bizzy@example.com" }
    }
  ],
  "received_transfer": null,
  "transfer_link": { "url": null, "blocked_reason": "transferred" }
}
Field Description
status pending (waiting on the recipient), accepted, declined, or canceled (by the sender before acceptance).
origin manual (a person started it) or auto (the app started it because the buyer named a companion at checkout).
ticket_id The ticket being transferred.
replacement_ticket_id The ticket issued to the recipient. null until the transfer is accepted.
recipient_id The contact the ticket is going to. recipient is the contact record, returned with .recipient in include.
recipient_name The name the sender gave for this transfer; the ticket issued on acceptance carries it. Can differ from recipient.name when one contact (one email) receives several tickets for different people. Falls back to the contact’s name on transfers that recorded none.
sender_id The contact who held the ticket when the transfer started (the source ticket’s contact).

transfer_link.url is present only when a transfer can be started right now; otherwise blocked_reason says why. A pending transfer blocks a second one until it is accepted, declined or canceled.

blocked_reason Meaning
transferred Already transferred. The link lives on the ticket at replacement_ticket_id.
pending_transfer A transfer is pending on this ticket.
checked_in, checked_out, voided, pending Only confirmed tickets can be transferred.
event_ended The event is over.
downloaded The ticket was downloaded and its ticket type does not allow changes after download.
not_transferable The ticket type does not allow transfers.

Get ticket

GET /tickets/{id}

curl -X GET \
  'https://app.guestmanager.com/api/public/v2/tickets/8472134?include=contact,event_ticket_type.event,scans' \
  -H 'Authorization: Token abcdefg' \
  -H 'Content-Type: application/json'

Create ticket

POST /tickets

Creates a ticket directly — used for backend issuance (comps, invites, manual additions). Tickets created here have source: backend. Tickets created via the checkout flow are produced from line items and use source: line_item.

Create a comp ticket

curl -X POST \
  https://app.guestmanager.com/api/public/v2/tickets \
  -H 'Authorization: Token abcdefg' \
  -H 'Content-Type: application/json' \
  -d '{
    "ticket": {
      "event_id": 12345,
      "ticket_type_id": 2217,
      "name": "Jane Doe",
      "email": "jane@example.com",
      "list_id": 5678,
      "dispatch": true
    }
  }'

Request parameters

You can either pass event_id + ticket_type_id (and the API resolves them to an event_ticket_type_id), or pass event_ticket_type_id directly if you already have it.

A ticket created here has no order line item, so it has no ticket tier: the tier (the product variant a customer bought) comes only from an order. The Ticket column on the Event Ticketing app’s Attendees page and the Tier column in the Guest Manager dashboard stay blank for these tickets. To carry the tier when importing tickets from another system, create a ticket type per tier and pass its ticket_type_id, or store the tier name in a custom field.

Each ticket created here uses 1 credit from the account’s balance, whether or not it’s emailed. If you’re migrating existing bookings from another system, contact support before the import with roughly how many tickets you’re bringing over, and we’ll add a one-time credit to cover it.

A ticket type that’s archived can’t be used: the request returns 422. Unarchive it or choose another ticket type.

Parameter Type Description
ticket[event_id] integer Event the ticket belongs to. Required if event_ticket_type_id is not provided.
ticket[ticket_type_id] integer Ticket type. Required if event_ticket_type_id is not provided.
ticket[event_ticket_type_id] integer The pre-resolved event-ticket-type link. Alternative to event_id + ticket_type_id.
ticket[name] string Attendee name.
ticket[email] string Attendee email.
ticket[contact_id] integer Existing contact to attach the ticket to.
ticket[list_id] integer Event list to add the ticket to. Defaults to the event’s primary list.
ticket[permanent_list_id] integer Permanent list (cross-event) to associate with this ticket.
ticket[barcode_id] integer Pre-allocated barcode pool entry. For events using enforce_barcode_pool.
ticket[barcode] string Specific barcode value to assign. Use only when intentionally overriding the auto-generated barcode.
ticket[dispatch] boolean true to immediately email the ticket on creation. Defaults to false — the ticket is created silently, no email is sent. Use PATCH /tickets/{id}/email to send it later.
ticket[custom_fields] array Array of { id?, label, value } form responses. See Custom fields.

Custom fields

Custom fields capture event-specific responses (e.g., dietary restrictions, t-shirt size). Pass as an array of {label, value} pairs. Labels must be unique within a single ticket.

{
  "ticket": {
    "event_id": 12345,
    "ticket_type_id": 2217,
    "name": "Jane Doe",
    "custom_fields": [
      { "label": "T-shirt size", "value": "L" },
      { "label": "Dietary",       "value": "Vegetarian" }
    ]
  }
}

The API resolves each label to the appropriate question configured on the event. Unknown labels are silently ignored (validate labels client-side before submitting).

Update ticket

PATCH /tickets/{id}

Same field shape as create. Common updates: changing the attendee name/email, adding/updating custom field responses, attaching a barcode.

curl -X PATCH \
  https://app.guestmanager.com/api/public/v2/tickets/8472134 \
  -H 'Authorization: Token abcdefg' \
  -H 'Content-Type: application/json' \
  -d '{
    "ticket": {
      "name": "Jane Smith",
      "custom_fields": [
        { "label": "T-shirt size", "value": "M" }
      ]
    }
  }'

Moving a ticket to another event

To change a ticket’s date, pass the new event’s event_ticket_type_id (or event_id + ticket_type_id) along with a list_id on that event. Without one, the request returns 422 with “List does not belong to this event.”

These tickets can’t be moved to another event, and the request returns 422 with type invalid_state:

  • Tickets that belong to an order. Exchange them on the order instead.
  • Tickets in a party, whether the party’s leader or a member.

Moving a ticket doesn’t email the attendee. Use PATCH /tickets/{id}/email to resend it.

Delete ticket

DELETE /tickets/{id}

Soft-deletes (discards) the ticket. Returns 204 No Content. The ticket can be restored from the admin UI; deleted tickets do not appear in GET /tickets unless you pass filter[deleted]=true.

Void ticket

PATCH /tickets/{id}/void

Voids the ticket: the barcode is rejected at check-in and the ticket stays on its order for your records. Voiding does not refund the order and does not release the seat in Shopify. Only tickets with status confirmed, checked_in or checked_out can be voided.

Parameter Type Description
notify boolean Email the ticket holder that the ticket was voided. Default true.
reason string Optional. Stored as a note on the ticket (Voided: <reason>), visible in the Guest Manager dashboard.
Status Meaning
200 Voided. Returns the ticket.
422 type: invalid_state. The ticket is already voided, transferred or pending.
404 The ticket does not exist or was deleted.

Resend ticket email

PATCH /tickets/{id}/email

Sends the ticket email to the current email address on the ticket. Useful for “I lost my ticket” support flows.

Set ticket photo

PATCH /tickets/{id}/photo

Attaches a photo to the ticket — typically a headshot for identity verification at check-in.

Parameter Type Description
image string Base64-encoded image data. The server processes via Base64ImageProcessor.
ticket[photo] multipart Alternative: send photo as a multipart upload field on the standard update endpoint.

Check-in operations

The check-in endpoints are designed for high-throughput on-site scanning — typically called by the iOS scanner app or a purpose-built kiosk integration.

Device, station, employee headers

All check-in endpoints accept three optional request headers that attribute the scan:

Header Description
X-Device-Id The scanning device’s ID (registered in the company’s device list).
X-Station-Id The check-in station’s ID.
X-Employee-Id The employee performing the scan.

Including these headers populates the scan record’s audit trail and enables per-station / per-employee reporting.

Check in a ticket

PATCH /tickets/{id_or_barcode}/check_in

Checks in a ticket by ID or by barcode (set ?barcode=true and pass the barcode value as the id segment).

Check in by ID

curl -X PATCH \
  https://app.guestmanager.com/api/public/v2/tickets/8472134/check_in \
  -H 'Authorization: Token abcdefg' \
  -H 'X-Device-Id: 42' \
  -H 'X-Station-Id: 7' \
  -H 'X-Employee-Id: 99' \
  -H 'Content-Type: application/json'

Check in by barcode

curl -X PATCH \
  'https://app.guestmanager.com/api/public/v2/tickets/ABC123XYZ/check_in?barcode=true' \
  -H 'Authorization: Token abcdefg' \
  -H 'X-Device-Id: 42'

Response shape

The response includes the ticket plus a meta block with the scan record, a confirmation message, and (when applicable) the linked Shopify order ID:

{
  "data": { /* ticket */ },
  "meta": {
    "scan": {
      "id": 99812,
      "action": "checkin",
      "successful": true,
      "scanned_at": "2026-09-15T20:14:33Z"
    },
    "shopify_order_id": "gid://shopify/Order/4231887",
    "message": "Jane Doe's GA (Standard Entry) to Tasting Tour on September 15, 2026"
  }
}

Status codes

Code Meaning
202 Successful scan.
412 Scan rejected — ticket voided, expired, already checked in, or barcode unrecognized. Check meta.scan.action.

If the barcode is unrecognized entirely, the response is 412 with meta.scan.action: "unknown" and no data field.

Check out a ticket

PATCH /tickets/{id_or_barcode}/check_out

Records a check-out scan. Use for events that track re-entry windows.

Undo check-in

DELETE /tickets/{id}/check_in

Reverses the most recent check-in scan. Use for accidental scans.

Bulk check-in

PATCH /tickets/check_in

Checks in many tickets in a single request — useful for “scan a group all at once” workflows.

curl -X PATCH \
  https://app.guestmanager.com/api/public/v2/tickets/check_in \
  -H 'Authorization: Token abcdefg' \
  -H 'X-Device-Id: 42' \
  -H 'Content-Type: application/json' \
  -d '{ "ids": [8472134, 8472135, 8472136] }'

Response is a collection of tickets plus a meta.scans array with one scan record per ticket.


Bulk operations

Bulk email

PATCH /tickets/bulk_email

Sends a custom email to many ticket holders in one call. Backed by an Email::CompanyEmail::TicketMultipleEmail job; the response returns the email job record.

Parameter Type Description
ids array Array (or comma separated string) of ticket IDs.
email_template_id integer Required. The email template to use.
subject string Override the template subject.
body string Optional body override (rich text / HTML).
email string Override the recipient email (defaults to each ticket’s email).