The Ticket Validation API is what you reach for when BrightStar's built-in scanner isn't the whole story — when you're running your own check-in app at a kirtan door, wiring a third-party scanner into a retreat's gate, or building an automated access control system that needs to know who's allowed through and who already came in. It's a REST API, and it covers the three jobs any door needs done: checking whether a ticket is real, marking a ticket as arrived, and looking an attendee up. Because it's the same set of endpoints BrightStar's own scanner uses, building against it means building against something that's already been run through a real gate on a real morning.
What's the difference between validating a ticket and checking it in?
BrightStar splits looking at a ticket from acting on it into two separate calls. POST /v1/tickets/validate checks whether a ticket is real and returns its details — attendee name, ticket type, whether it's already been checked in — without changing anything. POST /v1/tickets/checkin does the same lookup and then writes the arrival: it marks the ticket checked in and stamps the moment it happened. If you only ever call /checkin, every read becomes a write, and there's no way to glance at a ticket without also using it up. Keeping the two separate means a volunteer can test a scanner, or answer 'is this a real ticket' at the merch table, without accidentally marking someone present before they've walked through the gate.
What happens when you check a ticket in?
A check-in call does two things at once: it confirms the ticket is good, and it commits the arrival. Here's what happens between sending the request and getting your response back:
- 1You send the ticket_id, and BrightStar looks it up against the ticket's real record.
- 2A ticket can be identified directly by its ticket_id, which is what a camera scanner reads at the gate, or by a time-limited code — that path also confirms the code hasn't expired or already been used, and marks it used before the check-in itself goes through.
- 3If the ticket is valid for this event and hasn't already been used, BrightStar marks it checked in and records the exact timestamp.
- 4You get back the attendee name, the ticket type, and the checked_in_at time that was just written.
- 5You can optionally attach a scanner_id and a GPS location, so the check-in record carries where and on what device it happened.
What happens when the API says no?
Not every rejection means the same thing, and treating them all alike at the door creates confusion. A ticket that doesn't exist returns INVALID_TICKET with a 404 — the ID was typed wrong, or it isn't a BrightStar ticket at all. ALREADY_CHECKED_IN, WRONG_EVENT, TICKET_CANCELLED, and EVENT_NOT_STARTED all come back as 400s: the ticket exists, but something about its state stops it going through. ALREADY_CHECKED_IN comes with the timestamp of the original scan, which is often enough to settle a 'someone's trying to use my ticket' conversation on the spot. WRONG_EVENT catches a ticket from one gathering being waved at the gate of another — useful at a multi-day festival where several stages each run their own check-in. TICKET_CANCELLED means the ticket was refunded and shouldn't be honored. EVENT_NOT_STARTED means check-in hasn't opened yet, which is a state, not a problem with the ticket itself. Separate from all of this, an authorization failure means the request itself wasn't allowed, regardless of the ticket. A missing, expired, or revoked credential comes back as 401 — re-authenticate and try again. A credential that's valid but was never granted access to this particular event comes back as 403, which means the device or person calling the API was never scoped to scan here, and retrying won't change that.
How do you know who scanned a ticket, and when?
BrightStar fires a ticket.checked_in webhook the moment a ticket is scanned, and the payload carries the ticket ID, the attendee, the timestamp, and the scanner_id — so any system listening can update its own view of the door in real time instead of polling for changes. If a check-in gets undone, a ticket.check_in_reverted webhook fires too, naming who reverted it and why, so the correction is on record rather than silently disappearing. The scanner_id you send with a check-in request is also what shows up in that webhook, which is why it's worth naming devices for the post they're stationed at — entrance_main, say — rather than for whoever happens to be holding the phone that day. An optional GPS location can ride along with the same request, giving you a record of where, not just when, a ticket was used.
Who is allowed to call this API?
Access to the Validation API is scoped, not open-ended. A device or person authenticates once, and that session carries an explicit list of which events it's allowed to touch — a request naming any other event is refused outright, so a scanner set up for one retreat can't be pointed at another's guest list. Sessions can be revoked from the event's scanner-devices screen, and BrightStar rechecks that a session hasn't been revoked or expired on every single call, rather than trusting a credential just because it was valid earlier. That matters most at the end of a gathering, or the moment a volunteer's phone goes missing.