Reference

# Tickets reference.

Generated XRPC reference, field-level schemas, payload schemas, lexicons, errors, security, public review, and glossary.

[Read as Markdown](https://atmosphere.tickets/docs/reference.md) · [Agent build guide](https://atmosphere.tickets/docs/agent-start.md)

Developer beta SDK beta 0.0.0-beta.5 30 ticket lexicons Multi-app shared config roadmap

[Quickstart](https://atmosphere.tickets/docs.html#quickstart) [Read ATM docs](https://atmosphere.money/docs)

[Overview](https://atmosphere.tickets/docs.html) [Build](https://atmosphere.tickets/docs-build.html) [Callbacks](https://atmosphere.tickets/docs-callbacks.html) [Reference](https://atmosphere.tickets/docs-reference.html) [Operations](https://atmosphere.tickets/docs-operations.html)

## Lexicons

The 30 copied schemas come from ATM's canonical generated output. Public records describe safe catalog metadata; private service contracts describe authorized operations. This is separate from authoritative namespace publication and deployed release readiness.

| ticketType | Public event/type metadata and optional Product/default Price refs. Paid service configuration requires a matching active organizer-owned ticket Product; free/RSVP types may omit it. |
| --- | --- |
| ticketedEvent | Public event anchor and optional display-ordered ticketTypes refs. Live availability, codes and eligibility stay private. |
| checkInList | Public label only; scanner permissions, logs and pass secrets stay private. |
| Capacity | Private type pools plus optional shared event cap through `setEventCapacity`; no public capacity-pool record. |
| Public discovery | Unauthenticated `listPublicConfig` on ATM AppView requires `organizer` and optional same-organizer `eventUri`. It is not live inventory. |

## Generated XRPC reference

This table is generated from `lexicons/tickets/atmosphere` so it stays aligned with the contract set used by the ATM runtime. The JSON lexicons remain the source of truth; this reference is the human-readable index.

Scrollable reference

| Method or record | Kind | Auth | Purpose | Links |
| --- | --- | --- | --- | --- |
| tickets.atmosphere.acceptCollaboration | procedure | app service-auth + required co-organizer assertion | Accept a pending co-organizer invitation (dual-consent: app service-auth plus the co-organizer's own assertion). | [Raw](https://atmosphere.tickets/lexicons/tickets/atmosphere/acceptCollaboration.json)[Fields](https://atmosphere.tickets/docs-reference.html#fields-tickets-atmosphere-acceptcollaboration)[Examples](https://atmosphere.tickets/docs-reference.html#api-reference)[Errors](https://atmosphere.tickets/docs-reference.html#fields-tickets-atmosphere-acceptcollaboration) |
| tickets.atmosphere.archiveTicketType | procedure | app service-auth + primary-organizer authority | Archive an organizer-owned ATM ticket type. | [Raw](https://atmosphere.tickets/lexicons/tickets/atmosphere/archiveTicketType.json)[Fields](https://atmosphere.tickets/docs-reference.html#fields-tickets-atmosphere-archivetickettype)[Examples](https://atmosphere.tickets/docs-reference.html#api-reference)[Errors](https://atmosphere.tickets/docs-reference.html#fields-tickets-atmosphere-archivetickettype) |
| tickets.atmosphere.cancelTicketEvent | procedure | app service-auth + primary-organizer authority | Irreversibly cancel an ATM ticketed event. | [Raw](https://atmosphere.tickets/lexicons/tickets/atmosphere/cancelTicketEvent.json)[Fields](https://atmosphere.tickets/docs-reference.html#fields-tickets-atmosphere-cancelticketevent)[Examples](https://atmosphere.tickets/docs-reference.html#api-reference)[Errors](https://atmosphere.tickets/docs-reference.html#fields-tickets-atmosphere-cancelticketevent) |
| tickets.atmosphere.checkInList | record | organizer repo write | Public check-in list label for an event. | [Raw](https://atmosphere.tickets/lexicons/tickets/atmosphere/checkInList.json)[Fields](https://atmosphere.tickets/docs-reference.html#fields-tickets-atmosphere-checkinlist)[Examples](https://atmosphere.tickets/docs-reference.html#api-reference)[Errors](https://atmosphere.tickets/docs-reference.html#fields-tickets-atmosphere-checkinlist) |
| tickets.atmosphere.checkInTicket | procedure | app service-auth | Verify and check in a private ATM Tickets scan token. | [Raw](https://atmosphere.tickets/lexicons/tickets/atmosphere/checkInTicket.json)[Fields](https://atmosphere.tickets/docs-reference.html#fields-tickets-atmosphere-checkinticket)[Examples](https://atmosphere.tickets/docs-reference.html#api-reference)[Errors](https://atmosphere.tickets/docs-reference.html#fields-tickets-atmosphere-checkinticket) |
| tickets.atmosphere.claimFreeTicket | procedure | app service-auth + required buyer assertion | Atomically claim zero-price scarce tickets for a verified buyer without checkout redirect. | [Raw](https://atmosphere.tickets/lexicons/tickets/atmosphere/claimFreeTicket.json)[Fields](https://atmosphere.tickets/docs-reference.html#fields-tickets-atmosphere-claimfreeticket)[Examples](https://atmosphere.tickets/docs-reference.html#api-reference)[Errors](https://atmosphere.tickets/docs-reference.html#fields-tickets-atmosphere-claimfreeticket) |
| tickets.atmosphere.claimWaitlistOffer | procedure | app service-auth + buyer assertion when buyerDid is supplied | Claim a ticket waitlist OFFER by starting checkout against its already-reserved offer hold. | [Raw](https://atmosphere.tickets/lexicons/tickets/atmosphere/claimWaitlistOffer.json)[Fields](https://atmosphere.tickets/docs-reference.html#fields-tickets-atmosphere-claimwaitlistoffer)[Examples](https://atmosphere.tickets/docs-reference.html#api-reference)[Errors](https://atmosphere.tickets/docs-reference.html#fields-tickets-atmosphere-claimwaitlistoffer) |
| tickets.atmosphere.createTicketEvent | procedure | app service-auth + organizer assertion unless app is organizer | Create or upsert an organizer-owned ATM ticketed-event config shell for a public event. | [Raw](https://atmosphere.tickets/lexicons/tickets/atmosphere/createTicketEvent.json)[Fields](https://atmosphere.tickets/docs-reference.html#fields-tickets-atmosphere-createticketevent)[Examples](https://atmosphere.tickets/docs-reference.html#api-reference)[Errors](https://atmosphere.tickets/docs-reference.html#fields-tickets-atmosphere-createticketevent) |
| tickets.atmosphere.createTicketHold | procedure | app service-auth + buyer assertion when buyerDid is supplied | Atomically reserve ticket capacity and return an ATM checkout URL. | [Raw](https://atmosphere.tickets/lexicons/tickets/atmosphere/createTicketHold.json)[Fields](https://atmosphere.tickets/docs-reference.html#fields-tickets-atmosphere-createtickethold)[Examples](https://atmosphere.tickets/docs-reference.html#api-reference)[Errors](https://atmosphere.tickets/docs-reference.html#fields-tickets-atmosphere-createtickethold) |
| tickets.atmosphere.createTicketType | procedure | app service-auth + organizer assertion unless app is organizer | Create an organizer-owned ATM ticket type and optional public ticket-type record refs for an event. | [Raw](https://atmosphere.tickets/lexicons/tickets/atmosphere/createTicketType.json)[Fields](https://atmosphere.tickets/docs-reference.html#fields-tickets-atmosphere-createtickettype)[Examples](https://atmosphere.tickets/docs-reference.html#api-reference)[Errors](https://atmosphere.tickets/docs-reference.html#fields-tickets-atmosphere-createtickettype) |
| tickets.atmosphere.defs | defs | shared definitions | No description in lexicon yet. | [Raw](https://atmosphere.tickets/lexicons/tickets/atmosphere/defs.json)[Fields](https://atmosphere.tickets/docs-reference.html#fields-tickets-atmosphere-defs)[Examples](https://atmosphere.tickets/docs-reference.html#api-reference)[Errors](https://atmosphere.tickets/docs-reference.html#fields-tickets-atmosphere-defs) |
| tickets.atmosphere.getTicketAvailability | query | app service-auth | Read app-scoped ticket availability derived from private ATM holds and issued tickets. | [Raw](https://atmosphere.tickets/lexicons/tickets/atmosphere/getTicketAvailability.json)[Fields](https://atmosphere.tickets/docs-reference.html#fields-tickets-atmosphere-getticketavailability)[Examples](https://atmosphere.tickets/docs-reference.html#api-reference)[Errors](https://atmosphere.tickets/docs-reference.html#fields-tickets-atmosphere-getticketavailability) |
| tickets.atmosphere.inviteOrganizerCollaboration | procedure | app service-auth + primary-organizer authority | Invite a co-organizer to operationally co-run a ticketed event (Part A: operational delegation only). | [Raw](https://atmosphere.tickets/lexicons/tickets/atmosphere/inviteOrganizerCollaboration.json)[Fields](https://atmosphere.tickets/docs-reference.html#fields-tickets-atmosphere-inviteorganizercollaboration)[Examples](https://atmosphere.tickets/docs-reference.html#api-reference)[Errors](https://atmosphere.tickets/docs-reference.html#fields-tickets-atmosphere-inviteorganizercollaboration) |
| tickets.atmosphere.joinWaitlist | procedure | app service-auth + buyer assertion when buyerDid is supplied | Join the FIFO waitlist for a sold-out ticket type. | [Raw](https://atmosphere.tickets/lexicons/tickets/atmosphere/joinWaitlist.json)[Fields](https://atmosphere.tickets/docs-reference.html#fields-tickets-atmosphere-joinwaitlist)[Examples](https://atmosphere.tickets/docs-reference.html#api-reference)[Errors](https://atmosphere.tickets/docs-reference.html#fields-tickets-atmosphere-joinwaitlist) |
| tickets.atmosphere.listBuyerTickets | query | app service-auth | List app-scoped issued tickets for a buyer or payment. | [Raw](https://atmosphere.tickets/lexicons/tickets/atmosphere/listBuyerTickets.json)[Fields](https://atmosphere.tickets/docs-reference.html#fields-tickets-atmosphere-listbuyertickets)[Examples](https://atmosphere.tickets/docs-reference.html#api-reference)[Errors](https://atmosphere.tickets/docs-reference.html#fields-tickets-atmosphere-listbuyertickets) |
| tickets.atmosphere.listCollaborations | procedure | app service-auth + event control or co-organizer assertion | List organizer collaborations for an event (authorized via event control) or the calling co-organizer's own collaboration rows. | [Raw](https://atmosphere.tickets/lexicons/tickets/atmosphere/listCollaborations.json)[Fields](https://atmosphere.tickets/docs-reference.html#fields-tickets-atmosphere-listcollaborations)[Examples](https://atmosphere.tickets/docs-reference.html#api-reference)[Errors](https://atmosphere.tickets/docs-reference.html#fields-tickets-atmosphere-listcollaborations) |
| tickets.atmosphere.listEventWaitlist | procedure | app service-auth + current event-control authority | List an organizer's event waitlist: a per-ticket-type rollup plus the paginated FIFO queue, each entry with its position and current offer status. | [Raw](https://atmosphere.tickets/lexicons/tickets/atmosphere/listEventWaitlist.json)[Fields](https://atmosphere.tickets/docs-reference.html#fields-tickets-atmosphere-listeventwaitlist)[Examples](https://atmosphere.tickets/docs-reference.html#api-reference)[Errors](https://atmosphere.tickets/docs-reference.html#fields-tickets-atmosphere-listeventwaitlist) |
| tickets.atmosphere.listOrganizerTickets | query | app service-auth | List app-scoped issued tickets for an organizer or event. | [Raw](https://atmosphere.tickets/lexicons/tickets/atmosphere/listOrganizerTickets.json)[Fields](https://atmosphere.tickets/docs-reference.html#fields-tickets-atmosphere-listorganizertickets)[Examples](https://atmosphere.tickets/docs-reference.html#api-reference)[Errors](https://atmosphere.tickets/docs-reference.html#fields-tickets-atmosphere-listorganizertickets) |
| tickets.atmosphere.listPublicConfig | query | public AppView read | List indexed public tickets.atmosphere ticket config records. | [Raw](https://atmosphere.tickets/lexicons/tickets/atmosphere/listPublicConfig.json)[Fields](https://atmosphere.tickets/docs-reference.html#fields-tickets-atmosphere-listpublicconfig)[Examples](https://atmosphere.tickets/docs-reference.html#api-reference)[Errors](https://atmosphere.tickets/docs-reference.html#fields-tickets-atmosphere-listpublicconfig) |
| tickets.atmosphere.listTicketFormResponses | procedure | app service-auth + current event-control authority | List the full private attendee form responses for an organizer's own event. | [Raw](https://atmosphere.tickets/lexicons/tickets/atmosphere/listTicketFormResponses.json)[Fields](https://atmosphere.tickets/docs-reference.html#fields-tickets-atmosphere-listticketformresponses)[Examples](https://atmosphere.tickets/docs-reference.html#api-reference)[Errors](https://atmosphere.tickets/docs-reference.html#fields-tickets-atmosphere-listticketformresponses) |
| tickets.atmosphere.releaseFreeTicket | procedure | app service-auth + required buyer assertion | Release a buyer's free-claim tickets back to capacity — the inverse of claimFreeTicket for un-RSVP flows. | [Raw](https://atmosphere.tickets/lexicons/tickets/atmosphere/releaseFreeTicket.json)[Fields](https://atmosphere.tickets/docs-reference.html#fields-tickets-atmosphere-releasefreeticket)[Examples](https://atmosphere.tickets/docs-reference.html#api-reference)[Errors](https://atmosphere.tickets/docs-reference.html#fields-tickets-atmosphere-releasefreeticket) |
| tickets.atmosphere.releaseTicketHold | procedure | app service-auth | Release an active ticket hold before checkout completes. | [Raw](https://atmosphere.tickets/lexicons/tickets/atmosphere/releaseTicketHold.json)[Fields](https://atmosphere.tickets/docs-reference.html#fields-tickets-atmosphere-releasetickethold)[Examples](https://atmosphere.tickets/docs-reference.html#api-reference)[Errors](https://atmosphere.tickets/docs-reference.html#fields-tickets-atmosphere-releasetickethold) |
| tickets.atmosphere.revokeCollaboration | procedure | app service-auth + primary-organizer authority (co-organizer may self-revoke) | Revoke a co-organizer collaboration. | [Raw](https://atmosphere.tickets/lexicons/tickets/atmosphere/revokeCollaboration.json)[Fields](https://atmosphere.tickets/docs-reference.html#fields-tickets-atmosphere-revokecollaboration)[Examples](https://atmosphere.tickets/docs-reference.html#api-reference)[Errors](https://atmosphere.tickets/docs-reference.html#fields-tickets-atmosphere-revokecollaboration) |
| tickets.atmosphere.setEventCapacity | procedure | app service-auth + primary-organizer authority | Set, change, or clear the shared EVENT capacity — one pool every ticket type of the event draws from, in addition to any per-type caps. | [Raw](https://atmosphere.tickets/lexicons/tickets/atmosphere/setEventCapacity.json)[Fields](https://atmosphere.tickets/docs-reference.html#fields-tickets-atmosphere-seteventcapacity)[Examples](https://atmosphere.tickets/docs-reference.html#api-reference)[Errors](https://atmosphere.tickets/docs-reference.html#fields-tickets-atmosphere-seteventcapacity) |
| tickets.atmosphere.setTicketTypeForm | procedure | app service-auth + current event-control authority | Set (or clear) the private per-ticket-type attendee form for a ticketed event. | [Raw](https://atmosphere.tickets/lexicons/tickets/atmosphere/setTicketTypeForm.json)[Fields](https://atmosphere.tickets/docs-reference.html#fields-tickets-atmosphere-settickettypeform)[Examples](https://atmosphere.tickets/docs-reference.html#api-reference)[Errors](https://atmosphere.tickets/docs-reference.html#fields-tickets-atmosphere-settickettypeform) |
| tickets.atmosphere.ticketedEvent | record | organizer repo write | Organizer-published ticketing anchor for an event: marks the event as ticketed and optionally discloses its ticket types in display order. | [Raw](https://atmosphere.tickets/lexicons/tickets/atmosphere/ticketedEvent.json)[Fields](https://atmosphere.tickets/docs-reference.html#fields-tickets-atmosphere-ticketedevent)[Examples](https://atmosphere.tickets/docs-reference.html#api-reference)[Errors](https://atmosphere.tickets/docs-reference.html#fields-tickets-atmosphere-ticketedevent) |
| tickets.atmosphere.ticketType | record | organizer repo write | Organizer-owned portable ticket type metadata for an AT Protocol event. | [Raw](https://atmosphere.tickets/lexicons/tickets/atmosphere/ticketType.json)[Fields](https://atmosphere.tickets/docs-reference.html#fields-tickets-atmosphere-tickettype)[Examples](https://atmosphere.tickets/docs-reference.html#api-reference)[Errors](https://atmosphere.tickets/docs-reference.html#fields-tickets-atmosphere-tickettype) |
| tickets.atmosphere.updateTicketEvent | procedure | app service-auth + current event-control authority | Update an app-scoped ATM ticketed-event config shell for a public event. | [Raw](https://atmosphere.tickets/lexicons/tickets/atmosphere/updateTicketEvent.json)[Fields](https://atmosphere.tickets/docs-reference.html#fields-tickets-atmosphere-updateticketevent)[Examples](https://atmosphere.tickets/docs-reference.html#api-reference)[Errors](https://atmosphere.tickets/docs-reference.html#fields-tickets-atmosphere-updateticketevent) |
| tickets.atmosphere.updateTicketType | procedure | app service-auth + current event-control authority | Update organizer-owned ATM ticket type metadata. | [Raw](https://atmosphere.tickets/lexicons/tickets/atmosphere/updateTicketType.json)[Fields](https://atmosphere.tickets/docs-reference.html#fields-tickets-atmosphere-updatetickettype)[Examples](https://atmosphere.tickets/docs-reference.html#api-reference)[Errors](https://atmosphere.tickets/docs-reference.html#fields-tickets-atmosphere-updatetickettype) |
| tickets.atmosphere.verifyTicket | procedure | app service-auth | Verify a private ATM Tickets scan token without mutating check-in state. | [Raw](https://atmosphere.tickets/lexicons/tickets/atmosphere/verifyTicket.json)[Fields](https://atmosphere.tickets/docs-reference.html#fields-tickets-atmosphere-verifyticket)[Examples](https://atmosphere.tickets/docs-reference.html#api-reference)[Errors](https://atmosphere.tickets/docs-reference.html#fields-tickets-atmosphere-verifyticket) |

## Generated field reference

This section is regenerated from `lexicons/tickets/atmosphere`. It expands the contract index into field-level schema tables with location, type, required/nullable status, limits, and descriptions.

### tickets.atmosphere.acceptCollaboration 5 fields

| Location | Field | Type | Required | Nullable | Limits | Description |
| --- | --- | --- | --- | --- | --- | --- |
| input | environment | string<test \| live> | no | no | maxLength:16 | No description in lexicon yet. |
| input | collaborationId | string | yes | no | minLength:1, maxLength:300 | No description in lexicon yet. |
| input | coOrganizerDid | string | yes | no | format:did | The accepting co-organizer. Must match the invitation's named coOrganizerDid. |
| input | coOrganizerAssertionJwt | string | yes | no | maxLength:8192 | REQUIRED short-lived user service-auth JWT issued BY coOrganizerDid to ATM, scoped to tickets.atmosphere.acceptCollaboration. This is the co-organizer's consent: ATM verifies iss === coOrganizerDid and the route-scoped lxm before flipping the row to accepted. |
| output | collaboration | ref:tickets.atmosphere.defs#organizerCollaboration | yes | no | none | No description in lexicon yet. |

**Declared errors:** `AppNotRegistered` — Caller DID is not registered as an ATM app.; `TicketsModuleDisabled` — This app has not enabled ATM Tickets.; `CollaborationNotFound` — Collaboration invitation not found.; `CollaborationConsentRequired` — A valid co-organizer assertion (coOrganizerAssertionJwt) issued by coOrganizerDid is required to accept this invitation.; `CollaborationNotAcceptable` — This collaboration is not in a pending state, or coOrganizerDid does not match the named invitee.; `UserDidMismatch` — coOrganizerAssertionJwt issuer does not match coOrganizerDid.

### tickets.atmosphere.archiveTicketType 7 fields

| Location | Field | Type | Required | Nullable | Limits | Description |
| --- | --- | --- | --- | --- | --- | --- |
| input | environment | string<test \| live> | no | no | maxLength:16 | No description in lexicon yet. |
| input | ticketTypeId | string | yes | no | minLength:1, maxLength:300 | No description in lexicon yet. |
| input | organizerDid | string | no | no | format:did | The current primary organizer authorizing this mutation. Omit only when the calling app is itself the event's primary organizer. |
| input | organizerAssertionJwt | string | no | no | maxLength:8192 | Optional only for an app archiving its own event's ticket type. Otherwise, a short-lived user service-auth JWT from organizerDid to ATM scoped to tickets.atmosphere.archiveTicketType. |
| output | ticketType | ref:#ticketType | yes | no | none | No description in lexicon yet. |
| def:ticketType | id | string | yes | no | maxLength:300 | No description in lexicon yet. |
| def:ticketType | status | string<archived> | yes | no | maxLength:32 | No description in lexicon yet. |

**Declared errors:** `AppNotRegistered` — Caller DID is not registered as an ATM app.; `TicketsModuleDisabled` — This app has not enabled ATM Tickets.; `TicketTypeNotFound` — Ticket type not found.; `EventControlRequired` — A verified current event-controller authorization is required for this event.; `PrimaryOrganizerRequired` — Only the current primary organizer can archive a ticket type.; `UserDidMismatch` — organizerAssertionJwt issuer does not match organizerDid.

### tickets.atmosphere.cancelTicketEvent 13 fields

| Location | Field | Type | Required | Nullable | Limits | Description |
| --- | --- | --- | --- | --- | --- | --- |
| input | environment | string<test \| live> | no | no | maxLength:16 | No description in lexicon yet. |
| input | eventId | string | yes | no | minLength:1, maxLength:300 | No description in lexicon yet. |
| input | organizerDid | string | no | no | format:did | The current primary organizer authorizing cancellation. Omit only when the calling app is itself the event's primary organizer. |
| input | organizerAssertionJwt | string | no | no | maxLength:8192 | Optional only for an app canceling its own event. Otherwise, a short-lived user service-auth JWT from organizerDid to ATM scoped to tickets.atmosphere.cancelTicketEvent. |
| input | reason | string | yes | no | minLength:3, maxLength:10000, maxGraphemes:1000 | No description in lexicon yet. |
| output | cancellation | ref:#cancellation | yes | no | none | No description in lexicon yet. |
| def:cancellation | id | string | yes | no | maxLength:300 | No description in lexicon yet. |
| def:cancellation | eventId | string | yes | no | maxLength:300 | No description in lexicon yet. |
| def:cancellation | status | string<requested \| already-canceled> | yes | no | maxLength:32 | No description in lexicon yet. |
| def:cancellation | ticketCount | integer | yes | no | minimum:0 | No description in lexicon yet. |
| def:cancellation | paidTicketCount | integer | yes | no | minimum:0 | No description in lexicon yet. |
| def:cancellation | freeTicketCount | integer | yes | no | minimum:0 | No description in lexicon yet. |
| def:cancellation | releasedHoldCount | integer | yes | no | minimum:0 | No description in lexicon yet. |

**Declared errors:** `AppNotRegistered` — Caller DID is not registered as an ATM app.; `TicketsModuleDisabled` — This app has not enabled ATM Tickets.; `TicketEventNotFound` — Ticketed event config not found.; `EventControlRequired` — A verified current primary-organizer authorization is required for this event.; `UserDidMismatch` — organizerAssertionJwt issuer does not match organizerDid.; `InvalidCancellationReason` — Cancellation reason must be between 3 and 1000 characters.

### tickets.atmosphere.checkInList 5 fields

| Location | Field | Type | Required | Nullable | Limits | Description |
| --- | --- | --- | --- | --- | --- | --- |
| record | event | ref:com.atproto.repo.strongRef | yes | no | none | CID-pinned strongRef to the canonical public community.lexicon.calendar.event record. |
| record | name | string | yes | no | minLength:1, maxLength:1000, maxGraphemes:100 | No description in lexicon yet. |
| record | archived | boolean | no | no | none | True when this check-in list is archived. Omitted or false means it is not archived. |
| record | createdAt | string | yes | no | format:datetime | No description in lexicon yet. |
| record | updatedAt | string | no | no | format:datetime | No description in lexicon yet. |

### tickets.atmosphere.checkInTicket 8 fields

| Location | Field | Type | Required | Nullable | Limits | Description |
| --- | --- | --- | --- | --- | --- | --- |
| input | environment | string<test \| live> | no | no | maxLength:16 | No description in lexicon yet. |
| input | ticketToken | string | yes | no | minLength:1, maxLength:4000 | No description in lexicon yet. |
| input | checkInListId | string | no | no | minLength:1, maxLength:300 | No description in lexicon yet. |
| input | scannerDid | string | no | no | format:did | App-asserted staff DID recorded in the private check-in audit log. ATM does not independently verify this DID; the calling app is responsible for its scanner authentication. |
| input | metadata | unknown | no | no | none | No description in lexicon yet. |
| output | status | string<checked-in \| already-checked-in \| not-valid> | yes | no | maxLength:32 | No description in lexicon yet. |
| output | checkedInAt | string | no | no | format:datetime | No description in lexicon yet. |
| output | ticket | ref:tickets.atmosphere.defs#issuedTicket | no | no | none | No description in lexicon yet. |

**Declared errors:** `AppNotRegistered` — Caller DID is not registered as an ATM app.; `TicketsModuleDisabled` — This app has not enabled ATM Tickets.; `TicketNotFound` — Ticket not found or verification failed.; `CheckInListNotFound` — checkInListId does not exist for this event.; `CheckInListMismatch` — The ticket belongs to a different check-in list.; `InvalidCheckInList` — checkInListId is not usable for this ticket's event.

### tickets.atmosphere.claimFreeTicket 18 fields

| Location | Field | Type | Required | Nullable | Limits | Description |
| --- | --- | --- | --- | --- | --- | --- |
| input | environment | string<test \| live> | no | no | maxLength:16 | No description in lexicon yet. |
| input | eventId | string | no | no | minLength:1, maxLength:300 | No description in lexicon yet. |
| input | eventUri | string | no | no | format:at-uri | No description in lexicon yet. |
| input | buyerDid | string | yes | no | format:did | No description in lexicon yet. |
| input | buyerAssertionJwt | string | yes | no | maxLength:8192 | Required short-lived user service-auth JWT from buyerDid to ATM, scoped to tickets.atmosphere.claimFreeTicket. |
| input | customerEmail | string | no | no | maxLength:320 | Required delivery address for every new free-ticket claim. It remains wire-optional only so an exact idempotent replay of a legacy completed claim that had no email can still return that immutable result; omitting it for any fresh claim fails with CustomerEmailRequired. ATM normalizes and stores it privately and never writes it to protocol records. |
| input | customerName | string | no | no | minLength:1, maxLength:300 | Private attendee display name supplied by the buyer/app. Stored on the claim and issued tickets; never written to protocol records. |
| input | eventCode | string | no | no | minLength:3, maxLength:64 | Preferred buyer-entered event code. ATM applies its hidden-ticket unlock effect when required by the claim. |
| input | items | array<ref:tickets.atmosphere.defs#ticketHoldItemRequest> | yes | no | minLength:1, maxLength:20 | No description in lexicon yet. |
| input | accessCode | string | no | no | minLength:3, maxLength:64 | Legacy visibility-only input. New storefronts should use eventCode. Required when a requested hidden type is not unlocked by eventCode. |
| input | idempotencyKey | string | no | no | minLength:1, maxLength:200 | No description in lexicon yet. |
| input | metadata | unknown | no | no | none | No description in lexicon yet. |
| output | claimId | string | yes | no | maxLength:300 | No description in lexicon yet. |
| output | holdId | string | yes | no | maxLength:300 | No description in lexicon yet. |
| output | environment | string<test \| live> | yes | no | maxLength:16 | No description in lexicon yet. |
| output | items | array<ref:tickets.atmosphere.defs#ticketHoldItem> | yes | no | minLength:1, maxLength:20 | No description in lexicon yet. |
| output | tickets | array<ref:tickets.atmosphere.defs#issuedTicketWithContext> | yes | no | minLength:1, maxLength:1000 | No description in lexicon yet. |
| output | reused | boolean | no | no | none | No description in lexicon yet. |

**Declared errors:** `AppNotRegistered` — Caller DID is not registered as an ATM app.; `TicketsModuleDisabled` — This app has not enabled ATM Tickets.; `UnsupportedHistoricalCurrency` — Stored ticket data uses a historical currency that the current ISO 4217 wire contract cannot represent.; `UserAssertionRequired` — A verified buyer assertion (buyerAssertionJwt) is required to claim free tickets.; `AuthVerificationFailed` — The service-auth token could not be verified.; `UserDidMismatch` — buyerAssertionJwt issuer does not match buyerDid.; `InvalidItems` — At least one ticket type is required.; `InvalidQuantity` — Ticket quantity must be at least 1.; `InvalidCustomerEmail` — customerEmail is present but is not a valid delivery address.; `CustomerEmailRequired` — Every fresh free-ticket claim requires a delivery email; omission is accepted only for an exact replay of a legacy completed no-email claim.; `IdempotencyConflict` — This idempotency key was already used for a different buyer.; `FreeClaimBindingMismatch` — This idempotency key is already bound to a claim with different ticket types, quantities, attendee name, or delivery email.; `IdempotencyKeyInFlight` — A claim for this idempotency key is already being processed; retry to resume it.; `TicketTypeNotFound` — One or more ticket types were not found.; `MixedEvents` — A ticket claim can only contain ticket types from one event.; `MixedCurrency` — A ticket claim can only use one currency.; `TicketsUnavailable` — The ticket type is not currently available.; `PaidTicketRequiresCheckout` — Paid ticket types must use tickets.atmosphere.createTicketHold.; `QuantityTooHigh` — Requested quantity exceeds the per-claim maximum.; `InsufficientTicketCapacity` — Not enough capacity remains for the claim.; `TicketClaimMissing` — Claimed tickets could not be loaded after issuance.; `ClaimLimitReached` — This buyer already claimed the per-buyer maximum for a ticket type.; `InvalidEventCode` — The event code is invalid, unavailable, expired, or exhausted.; `EventCodeConflict` — eventCode was combined with a different legacy accessCode.; `AccessCodeRequired` — One or more requested ticket types are hidden and require an access code.; `InvalidAccessCode` — The access code is invalid, paused, expired, exhausted, or does not unlock every hidden ticket type in the request.; `TicketsBusy` — The inventory row is contended; retry shortly.

### tickets.atmosphere.claimWaitlistOffer 17 fields

| Location | Field | Type | Required | Nullable | Limits | Description |
| --- | --- | --- | --- | --- | --- | --- |
| input | environment | string<test \| live> | no | no | maxLength:16 | No description in lexicon yet. |
| input | waitlistId | string | yes | no | minLength:1, maxLength:300 | No description in lexicon yet. |
| input | buyerDid | string | no | no | format:did | No description in lexicon yet. |
| input | buyerAssertionJwt | string | no | no | maxLength:8192 | Required whenever buyerDid is supplied: a short-lived user service-auth JWT from buyerDid to ATM, scoped to tickets.atmosphere.claimWaitlistOffer. Omit both buyer fields for a guest email claim. |
| input | customerEmail | string | no | no | maxLength:320 | Private delivery/receipt hint. Stored privately by ATM; never written to protocol records. |
| input | customerName | string | no | no | minLength:1, maxLength:300 | Private attendee name for the issued ticket. Stored privately by ATM; never written to protocol records. |
| input | returnUrl | string | no | no | format:uri | No description in lexicon yet. |
| input | cancelUrl | string | no | no | format:uri | No description in lexicon yet. |
| output | waitlistId | string | yes | no | maxLength:300 | No description in lexicon yet. |
| output | holdId | string | yes | no | maxLength:300 | No description in lexicon yet. |
| output | statusToken | string | yes | no | maxLength:500 | Stable app-only capability for polling payment status. Persist it before redirecting; never place it in a browser URL. |
| output | token | string | yes | no | maxLength:500 | Rotatable browser checkout bearer. Prefer url for navigation; never persist this as the payment-status capability. |
| output | url | string | yes | no | format:uri | ATM browser checkout URL. Its embedded bearer may be retired when the payer changes accounts. |
| output | environment | string<test \| live> | no | no | maxLength:16 | No description in lexicon yet. |
| output | expiresAt | string | yes | no | format:datetime | No description in lexicon yet. |
| output | amount | integer | yes | no | minimum:0 | No description in lexicon yet. |
| output | currency | string | yes | no | minLength:3, maxLength:3 | Lowercase ISO 4217 alphabetic code matching money.atmosphere.price. Chargeability is enforced separately by the configured processor allowlist. Asset-denominated value uses the money.atmosphere.payment.defs value union, never this field. |

**Declared errors:** `AppNotRegistered` — Caller DID is not registered as an ATM app.; `TicketsModuleDisabled` — This app has not enabled ATM Tickets.; `UserAssertionRequired` — A verified buyer assertion is required whenever buyerDid is supplied.; `AuthVerificationFailed` — The buyer assertion could not be verified.; `InvalidRequest` — buyerDid and buyerAssertionJwt must be supplied together, or both omitted for a guest.; `UnsupportedHistoricalCurrency` — Stored ticket data uses a historical currency that the current ISO 4217 wire contract cannot represent.; `WaitlistEntryNotFound` — Waitlist entry not found.; `WaitlistOfferNotClaimable` — This waitlist entry has no active offer to claim.; `WaitlistOfferExpired` — This waitlist offer has expired.; `WaitlistOfferAlreadyClaimed` — This waitlist offer was already claimed.; `WaitlistClaimIdentityMismatch` — The claiming identity does not match the waitlist entry's buyer.; `LiveModeNotEnabled` — This app may not start live-environment checkouts yet.; `TicketCurrencyUnsupportedForFee` — This paid ticket currency is incompatible with the app's fixed ticket-fee denomination.; `UserDidMismatch` — buyerAssertionJwt issuer does not match buyerDid.

### tickets.atmosphere.createTicketEvent 8 fields

| Location | Field | Type | Required | Nullable | Limits | Description |
| --- | --- | --- | --- | --- | --- | --- |
| input | environment | string<test \| live> | no | no | maxLength:16 | No description in lexicon yet. |
| input | organizerDid | string | yes | no | format:did | No description in lexicon yet. |
| input | organizerAssertionJwt | string | no | no | maxLength:8192 | Optional short-lived user service-auth JWT from organizerDid to ATM, scoped to tickets.atmosphere.createTicketEvent. Proves the app is configuring ticketing with organizer consent. |
| input | event | ref:tickets.atmosphere.defs#eventInput | yes | no | none | No description in lexicon yet. |
| input | status | string<active \| paused \| archived> | no | no | maxLength:32 | ATM ticket-sales lifecycle state. It does not control visibility of the public event record. |
| input | eventCapacity | integer | no | no | minimum:1, maximum:250000 | Optional creation-time convenience for tickets.atmosphere.setEventCapacity: the shared capacity every ticket type of this event draws from. Omit for unlimited (the default). |
| input | metadata | unknown | no | no | none | No description in lexicon yet. |
| output | event | ref:tickets.atmosphere.defs#eventSummary | yes | no | none | No description in lexicon yet. |

**Declared errors:** `AppNotRegistered` — Caller DID is not registered as an ATM app.; `TicketsModuleDisabled` — This app has not enabled ATM Tickets.; `OrganizerNotRegistered` — Organizer has not signed in to ATM yet.; `PaymentSetupIncomplete` — Organizer has not finished ATM payment setup.; `OrganizerConsentRequired` — A verified organizer authorization (organizerAssertionJwt) is required to configure ticketing for this organizer.; `OrganizerReassignmentNotAllowed` — This event already belongs to a different organizer; a fresh organizer authorization is required to reassign it.; `UserDidMismatch` — organizerAssertionJwt issuer does not match organizerDid.

### tickets.atmosphere.createTicketHold 26 fields

| Location | Field | Type | Required | Nullable | Limits | Description |
| --- | --- | --- | --- | --- | --- | --- |
| input | environment | string<test \| live> | no | no | maxLength:16 | No description in lexicon yet. |
| input | eventId | string | no | no | minLength:1, maxLength:300 | No description in lexicon yet. |
| input | eventUri | string | no | no | format:at-uri | No description in lexicon yet. |
| input | buyerDid | string | no | no | format:did | Signed-in buyer DID. Must be accompanied by buyerAssertionJwt; omit both fields for guest checkout. ATM-hosted Tickets OAuth identity is resolved only from ATM's private server session and is never accepted through this field. |
| input | buyerAssertionJwt | string | no | no | maxLength:8192 | Short-lived user service-auth JWT from buyerDid to ATM, scoped to lxm money.atmosphere.payment.assertPayer. Must be accompanied by buyerDid; omit both fields for guest checkout. ATM verifies it inside the private checkout envelope. |
| input | payerBinding | string<switchable \| fixed> | no | no | maxLength:32 | Defaults to fixed when buyerDid and a matching verified buyerAssertionJwt are supplied; otherwise defaults to switchable. Explicit switchable permits changing accounts inside checkout and requires the app to reconcile CheckoutPayerChanged. Frozen with the hold; reusing an idempotency key cannot change it. |
| input | customerEmail | string | no | no | maxLength:320 | Private delivery/receipt hint for ticket emails. Stored privately by ATM; never written to protocol records. |
| input | customerName | string | no | no | minLength:1, maxLength:300 | Private attendee display name supplied by the buyer/app. Stored on the hold and issued tickets; never written to protocol records. |
| input | eventCode | string | no | no | minLength:3, maxLength:64 | Preferred buyer-entered event code. ATM resolves and enforces any discount, hidden-ticket unlock, or combined effects while creating the hold. |
| input | offerCode | string | no | no | minLength:3, maxLength:64 | Legacy discount-only input. New storefronts should use eventCode. ATM enforces eligibility, schedule, and usage limits while reserving the hold. |
| input | accessCode | string | no | no | minLength:3, maxLength:64 | Legacy visibility-only input. New storefronts should use eventCode. Required when a requested hidden type is not unlocked by eventCode. |
| input | items | array<ref:tickets.atmosphere.defs#ticketHoldItemRequest> | yes | no | minLength:1, maxLength:20 | No description in lexicon yet. |
| input | returnUrl | string | no | no | format:uri | No description in lexicon yet. |
| input | cancelUrl | string | no | no | format:uri | No description in lexicon yet. |
| input | idempotencyKey | string | no | no | minLength:1, maxLength:200 | No description in lexicon yet. |
| input | metadata | unknown | no | no | none | No description in lexicon yet. |
| output | holdId | string | yes | no | maxLength:300 | No description in lexicon yet. |
| output | statusToken | string | yes | no | maxLength:500 | Stable app-only capability for polling payment status. Persist it before redirecting; never place it in a browser URL. |
| output | token | string | yes | no | maxLength:500 | Rotatable browser checkout bearer. Prefer url for navigation; never persist this as the payment-status capability. |
| output | url | string | yes | no | format:uri | ATM browser checkout URL. Its embedded bearer may be retired when the payer changes accounts. |
| output | environment | string<test \| live> | no | no | maxLength:16 | No description in lexicon yet. |
| output | expiresAt | string | yes | no | format:datetime | No description in lexicon yet. |
| output | amount | integer | yes | no | minimum:0 | Final buyer checkout amount in minor units after any order-level offer and passed-through ATM ticket fee. This may differ from the sum of item price snapshots. |
| output | currency | string | yes | no | minLength:3, maxLength:3 | Lowercase ISO 4217 alphabetic code matching money.atmosphere.price. Chargeability is enforced separately by the configured processor allowlist. Asset-denominated value uses the money.atmosphere.payment.defs value union, never this field. |
| output | items | array<ref:tickets.atmosphere.defs#ticketHoldItem> | yes | no | minLength:1, maxLength:20 | No description in lexicon yet. |
| output | reused | boolean | no | no | none | No description in lexicon yet. |

**Declared errors:** `UnsupportedHistoricalCurrency` — Stored ticket data uses a historical currency that the current ISO 4217 wire contract cannot represent.; `InvalidBuyerIdentity` — buyerDid and buyerAssertionJwt were not supplied together, fixed binding lacked authenticated buyer identity, or trusted and app-supplied buyer identity were combined.; `InvalidPayerBinding` — The reservation's frozen payer-binding policy is missing or inconsistent.; `InvalidCustomerEmail` — customerEmail is not a valid delivery email address.; `AppNotRegistered` — Caller DID is not registered as an ATM app.; `TicketsModuleDisabled` — This app has not enabled ATM Tickets.; `OrganizerNotRegistered` — Organizer has not signed in to ATM yet.; `PaymentSetupIncomplete` — Organizer has not finished ATM payment setup.; `OrganizerConsentRequired` — A verified organizer authorization (organizerAssertionJwt) is required to configure ticketing for this organizer.; `OrganizerReassignmentNotAllowed` — This event already belongs to a different organizer; a fresh organizer authorization is required to reassign it.; `RecipientAppApprovalRequired` — The organizer has not approved this app to originate ticket payments.; `RecipientAppReapprovalRequired` — The app's ticket checkout terms changed and require renewed organizer approval.; `RecipientAppApprovalBlocked` — The organizer has blocked or revoked this app's ticket-payment approval.; `TicketProtocolRefsRequired` — Every paid ticket type requires a portable ticket or catalog reference.; `InvalidItems` — At least one ticket type is required.; `InvalidQuantity` — Ticket quantity must be at least 1.; `TicketTypeNotFound` — One or more ticket types were not found.; `MixedEvents` — A ticket hold can only contain ticket types from one event.; `MixedCurrency` — A ticket hold can only use one currency.; `TicketCurrencyUnsupportedForFee` — This paid ticket currency is incompatible with the app's fixed ticket-fee denomination.; `TicketsUnavailable` — The ticket type is not currently on sale.; `FreeTicketRequiresClaim` — Free ticket types must use tickets.atmosphere.claimFreeTicket.; `QuantityTooHigh` — Requested quantity exceeds the per-order maximum.; `InsufficientTicketCapacity` — Not enough capacity remains for the request.; `InvalidEventCode` — The event code is invalid, unavailable, expired, or exhausted.; `EventCodeConflict` — eventCode was combined with a different legacy offerCode or accessCode.; `OfferCodeInvalid` — The offer code is invalid, unavailable, expired, or does not apply to the requested ticket type.; `OfferRequiresSingleTicketType` — An offer code may currently be applied to only one ticket type per checkout.; `OfferNotAvailableForPayWhatYouWant` — Offer codes cannot be combined with pay-what-you-want ticket pricing.; `OfferCodeBusy` — The offer reservation is contended; retry shortly.; `AccessCodeRequired` — One or more requested ticket types are hidden and require an access code.; `InvalidAccessCode` — The access code is invalid, paused, expired, exhausted, or does not unlock every hidden ticket type in the request.; `IdempotencyKeyConflict` — The idempotency key was already used for a different ticket purchase.; `IdempotencyKeyInFlight` — A hold for this idempotency key is already being created; retry to resume it.; `CheckoutPayerChanged` — The payer changed accounts in ATM checkout; the initiating app must keep polling with the statusToken from the original result and cannot recover the rotated buyer bearer.; `LiveModeNotEnabled` — This app may not create live-environment holds yet.; `TicketsBusy` — The inventory row is contended; retry shortly.

### tickets.atmosphere.createTicketType 19 fields

| Location | Field | Type | Required | Nullable | Limits | Description |
| --- | --- | --- | --- | --- | --- | --- |
| input | environment | string<test \| live> | no | no | maxLength:16 | No description in lexicon yet. |
| input | organizerDid | string | yes | no | format:did | No description in lexicon yet. |
| input | organizerAssertionJwt | string | no | no | maxLength:8192 | Optional short-lived user service-auth JWT from organizerDid to ATM, scoped to tickets.atmosphere.createTicketType. Proves the app is configuring ticketing with organizer consent. |
| input | event | ref:tickets.atmosphere.defs#eventInput | yes | no | none | No description in lexicon yet. |
| input | title | string | yes | no | minLength:1, maxLength:1000, maxGraphemes:100 | No description in lexicon yet. |
| input | description | string | no | no | maxLength:10000, maxGraphemes:1000 | No description in lexicon yet. |
| input | currency | string | yes | no | minLength:3, maxLength:3 | Lowercase ISO 4217 alphabetic code matching money.atmosphere.price. Chargeability is enforced separately by the configured processor allowlist. Asset-denominated value uses the money.atmosphere.payment.defs value union, never this field. |
| input | unitAmount | integer | yes | no | minimum:0, maximum:2000000 | Amount in the smallest unit of currency. 0 creates a free ticket type (claimed via tickets.atmosphere.claimFreeTicket). A resulting paid ticket type must have an exact organizer-owned kind=ticket Product; paid amounts must also meet the processor minimum charge. |
| input | maxPerOrder | integer | no | no | minimum:1, maximum:50 | No description in lexicon yet. |
| input | saleStartsAt | string | no | no | format:datetime | No description in lexicon yet. |
| input | saleEndsAt | string | no | no | format:datetime | No description in lexicon yet. |
| input | ticketTypeRef | ref:com.atproto.repo.strongRef | no | no | none | No description in lexicon yet. |
| input | product | ref:com.atproto.repo.strongRef | no | no | none | Exact current organizer-owned money.atmosphere.product with kind=ticket. createTicketType requires it whenever unitAmount is greater than 0; a free type may omit it. updateTicketType requires the resulting paid type to retain or receive one, may attach or repoint it, and cannot clear it. The Product must be active and its exact default Price must be one-time, per-unit, and match the ticket amount and currency. |
| input | defaultPrice | ref:com.atproto.repo.strongRef | no | no | none | Legacy direct-Price compatibility only. New callers using product MUST omit defaultPrice; ATM derives and verifies Product.defaultPrice and rejects both fields together. Readers still accept this field on Product-less historical ticket types. |
| input | metadata | unknown | no | no | none | No description in lexicon yet. |
| input | visibility | string<public \| hidden> | no | no | maxLength:16 | Private buyer-facing visibility (default public). Hidden types are excluded from availability and buyer surfaces until unlocked by a ticket access code; organizer surfaces always see them. |
| input | quantityTotal | integer | no | no | minimum:1, maximum:250000 | Optional per-type cap. Omit for an unlimited type (the default). An event capacity set via tickets.atmosphere.setEventCapacity additionally bounds every type. |
| output | event | ref:tickets.atmosphere.defs#eventSummary | yes | no | none | No description in lexicon yet. |
| output | ticketType | ref:tickets.atmosphere.defs#ticketTypeSummary | yes | no | none | No description in lexicon yet. |

**Declared errors:** `AppNotRegistered` — Caller DID is not registered as an ATM app.; `TicketsModuleDisabled` — This app has not enabled ATM Tickets.; `OrganizerNotRegistered` — Organizer has not signed in to ATM yet.; `PaymentSetupIncomplete` — Organizer has not finished ATM payment setup.; `OrganizerConsentRequired` — A verified organizer authorization (organizerAssertionJwt) is required to configure ticketing for this organizer.; `OrganizerReassignmentNotAllowed` — This event already belongs to a different organizer; a fresh organizer authorization is required to reassign it.; `RecipientNotPayable` — The organizer has not completed payment setup for this environment.; `RecipientCurrencyUnavailable` — ATM could not verify the organizer's primary settlement currency.; `RecipientCurrencyUnsupported` — The organizer's primary settlement currency is not supported by ATM's current payment processor.; `RecipientCurrencyNotEnabled` — The organizer's primary settlement currency is not enabled in this ATM environment.; `RecipientCurrencyMismatch` — The paid ticket currency does not match the organizer's primary settlement currency.; `InvalidAmount` — Ticket price is invalid: negative, above the maximum, or a paid amount below the processor minimum charge (use 0 for free ticket types).; `TicketCurrencyUnsupportedForFee` — This paid ticket currency is incompatible with the app's fixed ticket-fee denomination.; `InvalidCapacity` — Ticket quantity must be at least 1.; `UserDidMismatch` — organizerAssertionJwt issuer does not match organizerDid.

### tickets.atmosphere.defs 109 fields

| Location | Field | Type | Required | Nullable | Limits | Description |
| --- | --- | --- | --- | --- | --- | --- |
| def:eventInput | uri | string | yes | no | format:at-uri | AT URI of the canonical public community.lexicon.calendar.event record. |
| def:eventInput | cid | string | no | no | format:cid | CID of the exact public event record revision represented by this snapshot. |
| def:eventInput | title | string | yes | no | minLength:1, maxLength:3000, maxGraphemes:300 | No description in lexicon yet. |
| def:eventInput | startsAt | string | no | no | format:datetime | No description in lexicon yet. |
| def:eventInput | imageUrl | string | no | no | format:uri | No description in lexicon yet. |
| def:ticketHoldItemRequest | ticketTypeId | string | yes | no | minLength:1, maxLength:300 | No description in lexicon yet. |
| def:ticketHoldItemRequest | quantity | integer | yes | no | minimum:1, maximum:50 | No description in lexicon yet. |
| def:ticketHoldItem | ticketTypeId | string | yes | no | maxLength:300 | No description in lexicon yet. |
| def:ticketHoldItem | title | string | yes | no | maxLength:1000, maxGraphemes:100 | No description in lexicon yet. |
| def:ticketHoldItem | quantity | integer | yes | no | minimum:1, maximum:50 | No description in lexicon yet. |
| def:ticketHoldItem | unitAmount | integer | yes | no | minimum:0 | No description in lexicon yet. |
| def:ticketHoldItem | currency | string | yes | no | minLength:3, maxLength:3 | Lowercase ISO 4217 alphabetic code matching money.atmosphere.price. Chargeability is enforced separately by the configured processor allowlist. Asset-denominated value uses the money.atmosphere.payment.defs value union, never this field. |
| def:ticketHoldItem | ticketTypeRef | ref:com.atproto.repo.strongRef | no | no | none | No description in lexicon yet. |
| def:ticketHoldItem | defaultPrice | ref:com.atproto.repo.strongRef | no | no | none | No description in lexicon yet. |
| def:ticketTypeSummary | id | string | yes | no | maxLength:300 | No description in lexicon yet. |
| def:ticketTypeSummary | eventId | string | yes | no | maxLength:300 | No description in lexicon yet. |
| def:ticketTypeSummary | title | string | yes | no | maxLength:1000, maxGraphemes:100 | No description in lexicon yet. |
| def:ticketTypeSummary | quantityTotal | integer | no | no | minimum:1, maximum:250000 | The type's own configured cap. Omitted when the type is uncapped. |
| def:ticketTypeSummary | currency | string | yes | no | minLength:3, maxLength:3 | Lowercase ISO 4217 alphabetic code matching money.atmosphere.price. Chargeability is enforced separately by the configured processor allowlist. Asset-denominated value uses the money.atmosphere.payment.defs value union, never this field. |
| def:ticketTypeSummary | unitAmount | integer | yes | no | minimum:0 | No description in lexicon yet. |
| def:ticketTypeSummary | status | string<active \| paused \| archived> | yes | no | maxLength:32 | No description in lexicon yet. |
| def:ticketTypeSummary | ticketTypeRef | ref:com.atproto.repo.strongRef | no | no | none | No description in lexicon yet. |
| def:ticketTypeSummary | product | ref:com.atproto.repo.strongRef | no | no | none | The canonical kind=ticket money.atmosphere.product this ticket type points at, when one is attached. Echoed so a writer can confirm the exact Product/CID ATM recorded rather than having to re-read the ticketType record. |
| def:ticketTypeSummary | defaultPrice | ref:com.atproto.repo.strongRef | no | no | none | No description in lexicon yet. |
| def:eventSummary | id | string | yes | no | maxLength:300 | ATM's private identifier for this ticketed-event config. |
| def:eventSummary | uri | string | yes | no | format:at-uri | AT URI of the canonical public event record. |
| def:eventSummary | cid | string | no | no | format:cid | CID of the exact public event record revision, when known. |
| def:eventSummary | eventRef | ref:com.atproto.repo.strongRef | no | no | none | No description in lexicon yet. |
| def:eventSummary | title | string | no | no | maxLength:3000, maxGraphemes:300 | No description in lexicon yet. |
| def:eventSummary | startsAt | string | no | no | format:datetime | No description in lexicon yet. |
| def:eventSummary | manageUrl | string | no | no | format:uri | Current ATM organizer-console locator for this canonical event. Refresh this value from ATM rather than constructing or indefinitely caching the route. The signed-in organizer's authority is revalidated by ATM; possession of this URL grants no access. |
| def:eventSummary | scannerUrl | string | no | no | format:uri | Stable first-party ATM scanner locator for this canonical event. The signed-in staff member still needs an active scanner grant; possession of this URL grants no access. |
| def:organizerCollaboration | id | string | yes | no | maxLength:300 | No description in lexicon yet. |
| def:organizerCollaboration | eventId | string | yes | no | maxLength:300 | No description in lexicon yet. |
| def:organizerCollaboration | primaryOrganizerDid | string | yes | no | format:did | No description in lexicon yet. |
| def:organizerCollaboration | coOrganizerDid | string | yes | no | format:did | No description in lexicon yet. |
| def:organizerCollaboration | role | string<co-organizer> | yes | no | maxLength:32 | No description in lexicon yet. |
| def:organizerCollaboration | status | string<pending \| accepted \| revoked> | yes | no | maxLength:16 | No description in lexicon yet. |
| def:organizerCollaboration | revenueShareBps | integer | no | no | minimum:0, maximum:10000 | Recorded revenue-share INTENT in basis points, for MANUAL RECONCILIATION ONLY. NOT an automatic split: ATM never transfers ticket revenue based on this value. |
| def:organizerCollaboration | invitedAt | string | yes | no | format:datetime | No description in lexicon yet. |
| def:organizerCollaboration | acceptedAt | string | no | no | format:datetime | No description in lexicon yet. |
| def:organizerCollaboration | revokedAt | string | no | no | format:datetime | No description in lexicon yet. |
| def:ticketAvailability | ticketTypeId | string | yes | no | maxLength:300 | No description in lexicon yet. |
| def:ticketAvailability | eventId | string | no | no | maxLength:300 | No description in lexicon yet. |
| def:ticketAvailability | title | string | yes | no | maxLength:1000, maxGraphemes:100 | No description in lexicon yet. |
| def:ticketAvailability | description | string | no | no | maxLength:10000, maxGraphemes:1000 | No description in lexicon yet. |
| def:ticketAvailability | currency | string | no | no | minLength:3, maxLength:3 | Lowercase ISO 4217 alphabetic code matching money.atmosphere.price. Chargeability is enforced separately by the configured processor allowlist. Asset-denominated value uses the money.atmosphere.payment.defs value union, never this field. |
| def:ticketAvailability | unitAmount | integer | no | no | minimum:0 | No description in lexicon yet. |
| def:ticketAvailability | status | string<available \| sold-out \| not-on-sale \| hidden \| unavailable> | yes | no | maxLength:32 | No description in lexicon yet. |
| def:ticketAvailability | visibility | string<hidden> | no | no | maxLength:16 | Present only for hidden ticket types revealed by the caller's access code, so an app can tell which entries the code unlocked. Public types omit the field. |
| def:ticketAvailability | availableQuantity | integer | no | no | minimum:0 | Effective availability (min across the type's capacity pools). Omitted when the type is unlimited. |
| def:ticketAvailability | quantityTotal | integer | no | no | minimum:1, maximum:250000 | The type's OWN configured cap, for 'X of Y left' display. Omitted when the type itself is uncapped (an event capacity may still bound availableQuantity). |
| def:ticketAvailability | heldQuantity | integer | no | no | minimum:0 | Quantity currently reserved by active holds. Returned only to authorized apps. |
| def:ticketAvailability | soldQuantity | integer | no | no | minimum:0 | Quantity already issued/sold. Returned only to authorized apps. |
| def:ticketAvailability | maxPerOrder | integer | yes | no | minimum:1, maximum:50 | No description in lexicon yet. |
| def:ticketAvailability | saleStartsAt | string | no | no | format:datetime | No description in lexicon yet. |
| def:ticketAvailability | saleEndsAt | string | no | no | format:datetime | No description in lexicon yet. |
| def:ticketPresentation | iconUrl | string | no | no | format:uri | Pass icon URL. Currently always returned (ATM falls back to a default icon); optional so a future presentation without an icon stays valid. |
| def:ticketPresentation | qr | ref:#ticketPresentationQr | yes | no | none | No description in lexicon yet. |
| def:ticketPresentation | app | ref:tickets.atmosphere.defs#brand | yes | no | none | No description in lexicon yet. |
| def:ticketPresentation | organizer | ref:tickets.atmosphere.defs#brand | yes | no | none | No description in lexicon yet. |
| def:ticketPresentation | event | ref:#ticketPresentationEvent | yes | no | none | No description in lexicon yet. |
| def:ticketPresentation | ticketType | ref:#ticketPresentationTicketType | yes | no | none | No description in lexicon yet. |
| def:brand | did | string | yes | no | format:did | No description in lexicon yet. |
| def:brand | handle | string | no | no | format:handle | No description in lexicon yet. |
| def:brand | name | string | yes | no | maxLength:300 | No description in lexicon yet. |
| def:brand | avatarUrl | string | no | no | format:uri | No description in lexicon yet. |
| def:issuedTicket | id | string | yes | no | maxLength:300 | No description in lexicon yet. |
| def:issuedTicket | eventId | string | yes | no | maxLength:300 | No description in lexicon yet. |
| def:issuedTicket | ticketTypeId | string | yes | no | maxLength:300 | No description in lexicon yet. |
| def:issuedTicket | paymentId | string | no | no | maxLength:300 | No description in lexicon yet. |
| def:issuedTicket | claimId | string | no | no | maxLength:300 | No description in lexicon yet. |
| def:issuedTicket | environment | string<test \| live> | yes | no | maxLength:16 | No description in lexicon yet. |
| def:issuedTicket | ownerDid | string | no | no | format:did | No description in lexicon yet. |
| def:issuedTicket | status | string<active \| voided \| refunded> | yes | no | maxLength:32 | No description in lexicon yet. |
| def:issuedTicket | ticketNumber | string | yes | no | maxLength:300 | No description in lexicon yet. |
| def:issuedTicket | eventRef | ref:com.atproto.repo.strongRef | no | no | none | No description in lexicon yet. |
| def:issuedTicket | ticketTypeRef | ref:com.atproto.repo.strongRef | no | no | none | No description in lexicon yet. |
| def:issuedTicket | defaultPrice | ref:com.atproto.repo.strongRef | no | no | none | No description in lexicon yet. |
| def:issuedTicket | scanToken | string | no | no | maxLength:4000 | Private scan token returned only to authorized clients. |
| def:issuedTicket | scanUrl | string | no | no | format:uri | No description in lexicon yet. |
| def:issuedTicket | createdAt | string | yes | no | format:datetime | No description in lexicon yet. |
| def:issuedTicket | updatedAt | string | yes | no | format:datetime | No description in lexicon yet. |
| def:issuedTicketWithContext | id | string | yes | no | maxLength:300 | No description in lexicon yet. |
| def:issuedTicketWithContext | eventId | string | yes | no | maxLength:300 | No description in lexicon yet. |
| def:issuedTicketWithContext | ticketTypeId | string | yes | no | maxLength:300 | No description in lexicon yet. |
| def:issuedTicketWithContext | paymentId | string | no | no | maxLength:300 | No description in lexicon yet. |
| def:issuedTicketWithContext | claimId | string | no | no | maxLength:300 | No description in lexicon yet. |
| def:issuedTicketWithContext | environment | string<test \| live> | yes | no | maxLength:16 | No description in lexicon yet. |
| def:issuedTicketWithContext | ownerDid | string | no | no | format:did | No description in lexicon yet. |
| def:issuedTicketWithContext | status | string<active \| voided \| refunded> | yes | no | maxLength:32 | No description in lexicon yet. |
| def:issuedTicketWithContext | ticketNumber | string | yes | no | maxLength:300 | No description in lexicon yet. |
| def:issuedTicketWithContext | eventRef | ref:com.atproto.repo.strongRef | no | no | none | No description in lexicon yet. |
| def:issuedTicketWithContext | ticketTypeRef | ref:com.atproto.repo.strongRef | no | no | none | No description in lexicon yet. |
| def:issuedTicketWithContext | defaultPrice | ref:com.atproto.repo.strongRef | no | no | none | No description in lexicon yet. |
| def:issuedTicketWithContext | scanToken | string | no | no | maxLength:4000 | No description in lexicon yet. |
| def:issuedTicketWithContext | scanUrl | string | no | no | format:uri | No description in lexicon yet. |
| def:issuedTicketWithContext | createdAt | string | yes | no | format:datetime | No description in lexicon yet. |
| def:issuedTicketWithContext | updatedAt | string | yes | no | format:datetime | No description in lexicon yet. |
| def:issuedTicketWithContext | presentation | ref:tickets.atmosphere.defs#ticketPresentation | no | no | none | No description in lexicon yet. |
| def:issuedTicketWithContext | event | ref:tickets.atmosphere.defs#eventSummary | no | no | none | No description in lexicon yet. |
| def:issuedTicketWithContext | ticketType | ref:tickets.atmosphere.defs#ticketTypeSummary | no | no | none | No description in lexicon yet. |
| def:ticketPresentationQr | enabled | boolean | yes | no | none | No description in lexicon yet. |
| def:ticketPresentationQr | label | string | yes | no | maxLength:100 | No description in lexicon yet. |
| def:ticketPresentationEvent | uri | string | yes | no | format:at-uri | AT URI of the canonical public event record. |
| def:ticketPresentationEvent | title | string | yes | no | maxLength:3000, maxGraphemes:300 | No description in lexicon yet. |
| def:ticketPresentationEvent | startsAt | string | no | no | format:datetime | No description in lexicon yet. |
| def:ticketPresentationEvent | imageUrl | string | no | no | format:uri | No description in lexicon yet. |
| def:ticketPresentationTicketType | title | string | yes | no | maxLength:1000, maxGraphemes:100 | No description in lexicon yet. |

### tickets.atmosphere.getTicketAvailability 7 fields

| Location | Field | Type | Required | Nullable | Limits | Description |
| --- | --- | --- | --- | --- | --- | --- |
| params | environment | string<test \| live> | no | no | maxLength:16 | No description in lexicon yet. |
| params | eventId | string | no | no | minLength:1, maxLength:300 | No description in lexicon yet. |
| params | eventUri | string | no | no | format:at-uri | No description in lexicon yet. |
| params | eventCode | string | no | no | minLength:3, maxLength:64 | Preferred buyer-entered event code. ATM resolves discount, hidden-ticket unlock, or combined effects in the exact event namespace; reading availability never consumes a code. |
| params | accessCode | string | no | no | minLength:3, maxLength:64 | Legacy visibility-only input. New storefronts should use eventCode; hidden ticket types are omitted unless the supplied code unlocks them. |
| output | event | ref:tickets.atmosphere.defs#eventSummary | no | no | none | No description in lexicon yet. |
| output | ticketTypes | array<ref:tickets.atmosphere.defs#ticketAvailability> | yes | no | maxLength:250 | No description in lexicon yet. |

**Declared errors:** `AppNotRegistered` — Caller DID is not registered as an ATM app.; `TicketsModuleDisabled` — This app has not enabled ATM Tickets.; `EventNotFound` — Ticketed event not found.; `UnsupportedHistoricalCurrency` — Stored ticket data uses a historical currency that the current ISO 4217 wire contract cannot represent.; `InvalidEventCode` — The event code is invalid, unavailable, expired, or exhausted.; `EventCodeConflict` — The event code conflicts with a different legacy code field.

### tickets.atmosphere.inviteOrganizerCollaboration 8 fields

| Location | Field | Type | Required | Nullable | Limits | Description |
| --- | --- | --- | --- | --- | --- | --- |
| input | environment | string<test \| live> | no | no | maxLength:16 | No description in lexicon yet. |
| input | eventId | string | no | no | minLength:1, maxLength:300 | No description in lexicon yet. |
| input | eventUri | string | no | no | format:at-uri | No description in lexicon yet. |
| input | organizerDid | string | yes | no | format:did | The inviting PRIMARY organizer (or an already-accepted co-organizer) authorizing this invite. |
| input | organizerAssertionJwt | string | no | no | maxLength:8192 | Optional short-lived user service-auth JWT from organizerDid to ATM, scoped to tickets.atmosphere.inviteOrganizerCollaboration. Proves the inviting organizer authorized the app to manage collaborations for this event. |
| input | coOrganizerDid | string | yes | no | format:did | The DID being invited to co-organize the event. |
| input | revenueShareBps | integer | no | no | minimum:0, maximum:10000 | OPTIONAL recorded revenue-share INTENT in basis points (0..10000), for MANUAL RECONCILIATION ONLY between the primary organizer and the co-organizer. This is NOT an automatic split: ATM never transfers or auto-pays any portion of ticket gross revenue based on this value. Ticket revenue settles entirely to the single primary organizer's connected account. |
| output | collaboration | ref:tickets.atmosphere.defs#organizerCollaboration | yes | no | none | No description in lexicon yet. |

**Declared errors:** `AppNotRegistered` — Caller DID is not registered as an ATM app.; `TicketsModuleDisabled` — This app has not enabled ATM Tickets.; `EventNotFound` — Ticketed event not found.; `EventControlRequired` — A verified primary-organizer or accepted co-organizer authorization is required for this event.; `InvalidCollaboration` — Invalid collaboration request (e.g. inviting the primary organizer as their own co-organizer, or an invalid revenueShareBps).; `CollaborationAlreadyAccepted` — An accepted collaboration already exists for this co-organizer.; `UserDidMismatch` — organizerAssertionJwt issuer does not match organizerDid.

### tickets.atmosphere.joinWaitlist 15 fields

| Location | Field | Type | Required | Nullable | Limits | Description |
| --- | --- | --- | --- | --- | --- | --- |
| input | environment | string<test \| live> | no | no | maxLength:16 | No description in lexicon yet. |
| input | eventId | string | no | no | minLength:1, maxLength:300 | No description in lexicon yet. |
| input | eventUri | string | no | no | format:at-uri | No description in lexicon yet. |
| input | ticketTypeId | string | yes | no | minLength:1, maxLength:300 | No description in lexicon yet. |
| input | buyerDid | string | no | no | format:did | No description in lexicon yet. |
| input | buyerAssertionJwt | string | no | no | maxLength:8192 | Required whenever buyerDid is supplied: a short-lived user service-auth JWT from buyerDid to ATM, scoped to tickets.atmosphere.joinWaitlist. Omit both buyer fields for a guest email waitlist entry. |
| input | customerEmail | string | no | no | maxLength:320 | Private delivery hint for the offer email. ATM stores only a MASKED hint; the raw email is never written to protocol records. |
| input | quantity | integer | no | no | minimum:1, maximum:50 | No description in lexicon yet. |
| output | waitlistId | string | yes | no | maxLength:300 | No description in lexicon yet. |
| output | status | string<waiting \| offered \| claimed \| expired \| released> | yes | no | maxLength:16 | No description in lexicon yet. |
| output | position | integer | yes | no | minimum:0 | No description in lexicon yet. |
| output | quantity | integer | yes | no | minimum:1 | No description in lexicon yet. |
| output | eventId | string | yes | no | maxLength:300 | No description in lexicon yet. |
| output | ticketTypeId | string | yes | no | maxLength:300 | No description in lexicon yet. |
| output | reused | boolean | no | no | none | No description in lexicon yet. |

**Declared errors:** `AppNotRegistered` — Caller DID is not registered as an ATM app.; `TicketsModuleDisabled` — This app has not enabled ATM Tickets.; `UnsupportedHistoricalCurrency` — Stored ticket data uses a historical currency that the current ISO 4217 wire contract cannot represent.; `UserAssertionRequired` — A verified buyer assertion is required whenever buyerDid is supplied.; `AuthVerificationFailed` — The buyer assertion could not be verified.; `InvalidRequest` — buyerDid and buyerAssertionJwt must be supplied together, or both omitted for a guest.; `InvalidWaitlistIdentity` — A buyerDid or customerEmail is required to join the waitlist.; `TicketTypeNotFound` — Ticket type not found.; `QuantityTooHigh` — Requested quantity exceeds the per-order maximum.; `UserDidMismatch` — buyerAssertionJwt issuer does not match buyerDid.

### tickets.atmosphere.listBuyerTickets 7 fields

| Location | Field | Type | Required | Nullable | Limits | Description |
| --- | --- | --- | --- | --- | --- | --- |
| params | environment | string<test \| live> | no | no | maxLength:16 | No description in lexicon yet. |
| params | buyer | string | no | no | format:at-identifier | DID or handle of the ticket owner. |
| params | paymentId | string | no | no | minLength:1, maxLength:300 | No description in lexicon yet. |
| params | limit | integer | no | no | minimum:1, maximum:100 | No description in lexicon yet. |
| params | cursor | string | no | no | maxLength:1024 | No description in lexicon yet. |
| output | tickets | array<ref:tickets.atmosphere.defs#issuedTicketWithContext> | yes | no | maxLength:100 | No description in lexicon yet. |
| output | cursor | string | no | no | maxLength:1024 | No description in lexicon yet. |

**Declared errors:** `AppNotRegistered` — Caller DID is not registered as an ATM app.; `TicketsModuleDisabled` — This app has not enabled ATM Tickets.; `InvalidCursor` — Ticket cursor is invalid.; `UnsupportedHistoricalCurrency` — Stored ticket data uses a historical currency that the current ISO 4217 wire contract cannot represent.

### tickets.atmosphere.listCollaborations 10 fields

| Location | Field | Type | Required | Nullable | Limits | Description |
| --- | --- | --- | --- | --- | --- | --- |
| input | environment | string<test \| live> | no | no | maxLength:16 | No description in lexicon yet. |
| input | eventId | string | no | no | minLength:1, maxLength:300 | No description in lexicon yet. |
| input | organizerDid | string | no | no | format:did | When listing an event's collaborations, the requesting organizer (verified via event control). |
| input | organizerAssertionJwt | string | no | no | maxLength:8192 | No description in lexicon yet. |
| input | coOrganizerDid | string | no | no | format:did | When listing a co-organizer's OWN collaborations, their DID (verified via coOrganizerAssertionJwt). |
| input | coOrganizerAssertionJwt | string | no | no | maxLength:8192 | No description in lexicon yet. |
| input | limit | integer | no | no | minimum:1, maximum:250 | No description in lexicon yet. |
| input | cursor | string | no | no | maxLength:1024 | No description in lexicon yet. |
| output | collaborations | array<ref:tickets.atmosphere.defs#organizerCollaboration> | yes | no | maxLength:250 | No description in lexicon yet. |
| output | cursor | string | no | no | maxLength:1024 | No description in lexicon yet. |

**Declared errors:** `AppNotRegistered` — Caller DID is not registered as an ATM app.; `TicketsModuleDisabled` — This app has not enabled ATM Tickets.; `EventNotFound` — Ticketed event not found.; `EventControlRequired` — A verified primary-organizer or accepted co-organizer authorization is required for this event.; `InvalidCollaborationQuery` — Provide eventId + organizerDid (event listing) or coOrganizerDid (own-rows listing).; `InvalidCursor` — Collaboration cursor is invalid.; `UserDidMismatch` — An assertion issuer does not match the expected DID.

### tickets.atmosphere.listEventWaitlist 30 fields

| Location | Field | Type | Required | Nullable | Limits | Description |
| --- | --- | --- | --- | --- | --- | --- |
| input | environment | string<test \| live> | no | no | maxLength:16 | No description in lexicon yet. |
| input | eventId | string | yes | no | minLength:1, maxLength:300 | No description in lexicon yet. |
| input | organizerDid | string | yes | no | format:did | No description in lexicon yet. |
| input | organizerAssertionJwt | string | no | no | maxLength:8192 | No description in lexicon yet. |
| input | ticketTypeId | string | no | no | minLength:1, maxLength:300 | Filter the queue to one ticket type. |
| input | includeTerminal | boolean | no | no | none | Include terminal (claimed/expired/released) rows in the queue page. Absent/false returns only active (waiting/offered) entries. The cursor paginates the entries queue only; summaries are always returned in full. |
| input | limit | integer | no | no | minimum:1, maximum:250 | No description in lexicon yet. |
| input | cursor | string | no | no | maxLength:1024 | No description in lexicon yet. |
| output | summaries | array<ref:#waitlistSummary> | yes | no | maxLength:1000 | No description in lexicon yet. |
| output | entries | array<ref:#waitlistEntry> | yes | no | maxLength:250 | No description in lexicon yet. |
| output | cursor | string | no | no | maxLength:1024 | No description in lexicon yet. |
| def:waitlistSummary | eventId | string | yes | no | maxLength:300 | No description in lexicon yet. |
| def:waitlistSummary | ticketTypeId | string | yes | no | maxLength:300 | No description in lexicon yet. |
| def:waitlistSummary | ticketTypeTitle | string | yes | no | maxLength:200 | No description in lexicon yet. |
| def:waitlistSummary | activeCount | integer | yes | no | minimum:0 | No description in lexicon yet. |
| def:waitlistSummary | waitingCount | integer | yes | no | minimum:0 | No description in lexicon yet. |
| def:waitlistSummary | offeredCount | integer | yes | no | minimum:0 | No description in lexicon yet. |
| def:waitlistSummary | activeQuantity | integer | yes | no | minimum:0 | No description in lexicon yet. |
| def:waitlistEntry | waitlistId | string | yes | no | maxLength:300 | No description in lexicon yet. |
| def:waitlistEntry | eventId | string | yes | no | maxLength:300 | No description in lexicon yet. |
| def:waitlistEntry | ticketTypeId | string | yes | no | maxLength:300 | No description in lexicon yet. |
| def:waitlistEntry | position | integer | yes | no | minimum:0 | No description in lexicon yet. |
| def:waitlistEntry | quantity | integer | yes | no | minimum:1 | No description in lexicon yet. |
| def:waitlistEntry | status | string<waiting \| offered \| claimed \| expired \| released> | yes | no | maxLength:16 | No description in lexicon yet. |
| def:waitlistEntry | buyerDid | string | no | no | format:did | No description in lexicon yet. |
| def:waitlistEntry | customerEmailHint | string | no | no | maxLength:200 | No description in lexicon yet. |
| def:waitlistEntry | offerHoldId | string | no | no | maxLength:300 | No description in lexicon yet. |
| def:waitlistEntry | offeredAt | string | no | no | format:datetime | No description in lexicon yet. |
| def:waitlistEntry | offerExpiresAt | string | no | no | format:datetime | No description in lexicon yet. |
| def:waitlistEntry | createdAt | string | yes | no | format:datetime | No description in lexicon yet. |

**Declared errors:** `AppNotRegistered` — Caller DID is not registered as an ATM app.; `TicketsModuleDisabled` — This app has not enabled ATM Tickets.; `EventNotFound` — Ticketed event not found.; `EventControlRequired` — A verified primary-organizer or accepted co-organizer authorization is required for this event.; `InvalidCursor` — Waitlist cursor is invalid.; `UserDidMismatch` — organizerAssertionJwt issuer does not match organizerDid.

### tickets.atmosphere.listOrganizerTickets 7 fields

| Location | Field | Type | Required | Nullable | Limits | Description |
| --- | --- | --- | --- | --- | --- | --- |
| params | environment | string<test \| live> | no | no | maxLength:16 | No description in lexicon yet. |
| params | organizer | string | no | no | format:at-identifier | DID or handle of the ticket organizer. |
| params | eventId | string | no | no | minLength:1, maxLength:300 | No description in lexicon yet. |
| params | limit | integer | no | no | minimum:1, maximum:250 | No description in lexicon yet. |
| params | cursor | string | no | no | maxLength:1024 | No description in lexicon yet. |
| output | tickets | array<ref:tickets.atmosphere.defs#issuedTicketWithContext> | yes | no | maxLength:250 | No description in lexicon yet. |
| output | cursor | string | no | no | maxLength:1024 | No description in lexicon yet. |

**Declared errors:** `AppNotRegistered` — Caller DID is not registered as an ATM app.; `TicketsModuleDisabled` — This app has not enabled ATM Tickets.; `InvalidCursor` — Ticket cursor is invalid.; `UnsupportedHistoricalCurrency` — Stored ticket data uses a historical currency that the current ISO 4217 wire contract cannot represent.

### tickets.atmosphere.listPublicConfig 30 fields

| Location | Field | Type | Required | Nullable | Limits | Description |
| --- | --- | --- | --- | --- | --- | --- |
| params | organizer | string | yes | no | format:at-identifier | DID or handle of the organizer. Handles are resolved to a DID before the indexed read. |
| params | eventUri | string | no | no | format:at-uri | No description in lexicon yet. |
| params | collections | array<string<tickets.atmosphere.ticketType \| tickets.atmosphere.ticketedEvent>> | no | no | maxLength:3 | No description in lexicon yet. |
| params | includeArchived | boolean | no | no | none | No description in lexicon yet. |
| params | limit | integer | no | no | minimum:1, maximum:100 | No description in lexicon yet. |
| params | cursor | string | no | no | maxLength:1024 | No description in lexicon yet. |
| output | records | array<ref:#publicConfigRecord> | yes | no | none | No description in lexicon yet. |
| output | cursor | string | no | no | maxLength:1024 | No description in lexicon yet. |
| def:publicConfigRecord | uri | string | yes | no | format:at-uri | AT URI of the indexed ticket config record. |
| def:publicConfigRecord | cid | string | yes | no | format:cid | CID of the exact indexed ticket config record revision. |
| def:publicConfigRecord | organizer | string | yes | no | format:did | DID of the organizer repository containing the record. |
| def:publicConfigRecord | collection | string<tickets.atmosphere.ticketType \| tickets.atmosphere.ticketedEvent> | yes | no | format:nsid | NSID of the indexed ticket config record collection. |
| def:publicConfigRecord | rkey | string | yes | no | format:record-key | Repository record key of the indexed ticket config record. |
| def:publicConfigRecord | event | ref:com.atproto.repo.strongRef | yes | no | none | CID-pinned strongRef to the public event this ticket config describes. |
| def:publicConfigRecord | title | string | no | no | maxLength:1000, maxGraphemes:100 | No description in lexicon yet. |
| def:publicConfigRecord | description | string | no | no | maxLength:10000, maxGraphemes:1000 | No description in lexicon yet. |
| def:publicConfigRecord | currency | string | no | no | minLength:3, maxLength:3 | Lowercase ISO 4217 alphabetic code matching money.atmosphere.price. Chargeability is enforced separately by the configured processor allowlist. Asset-denominated value uses the money.atmosphere.payment.defs value union, never this field. |
| def:publicConfigRecord | unitAmount | integer | no | no | minimum:0 | No description in lexicon yet. |
| def:publicConfigRecord | quantityTotal | integer | no | no | minimum:1, maximum:250000 | Display hint from the ticketType record. Omitted when uncapped or undisclosed. |
| def:publicConfigRecord | maxPerOrder | integer | no | no | minimum:1, maximum:50 | No description in lexicon yet. |
| def:publicConfigRecord | defaultPrice | ref:com.atproto.repo.strongRef | no | no | none | CID-pinned strongRef to the ticket type's current money.atmosphere.price, when published. |
| def:publicConfigRecord | saleStartsAt | string | no | no | format:datetime | No description in lexicon yet. |
| def:publicConfigRecord | saleEndsAt | string | no | no | format:datetime | No description in lexicon yet. |
| def:publicConfigRecord | ticketTypes | array<ref:com.atproto.repo.strongRef> | no | no | maxLength:250 | Display-ordered CID-pinned strongRefs advertised by a ticketed-event record. |
| def:publicConfigRecord | startsAt | string | no | no | format:datetime | No description in lexicon yet. |
| def:publicConfigRecord | endsAt | string | no | no | format:datetime | No description in lexicon yet. |
| def:publicConfigRecord | archived | boolean | yes | no | none | No description in lexicon yet. |
| def:publicConfigRecord | createdAt | string | no | no | format:datetime | No description in lexicon yet. |
| def:publicConfigRecord | updatedAt | string | no | no | format:datetime | No description in lexicon yet. |
| def:publicConfigRecord | indexedAt | string | yes | no | format:datetime | When the AppView indexed this public ticket config record. |

**Declared errors:** `InvalidRequest` — The query must include organizer, eventUri (if provided) must belong to that organizer, and only supported ticket config collections may be requested.

### tickets.atmosphere.listTicketFormResponses 16 fields

| Location | Field | Type | Required | Nullable | Limits | Description |
| --- | --- | --- | --- | --- | --- | --- |
| input | environment | string<test \| live> | no | no | maxLength:16 | No description in lexicon yet. |
| input | eventId | string | yes | no | minLength:1, maxLength:300 | No description in lexicon yet. |
| input | organizerDid | string | yes | no | format:did | No description in lexicon yet. |
| input | organizerAssertionJwt | string | no | no | maxLength:8192 | No description in lexicon yet. |
| input | ticketTypeId | string | no | no | minLength:1, maxLength:300 | No description in lexicon yet. |
| input | ticketId | string | no | no | minLength:1, maxLength:300 | No description in lexicon yet. |
| input | limit | integer | no | no | minimum:1, maximum:250 | No description in lexicon yet. |
| input | cursor | string | no | no | maxLength:1024 | No description in lexicon yet. |
| output | responses | array<ref:#formResponse> | yes | no | maxLength:250 | No description in lexicon yet. |
| output | cursor | string | no | no | maxLength:1024 | No description in lexicon yet. |
| def:formResponse | ticketId | string | yes | no | maxLength:300 | No description in lexicon yet. |
| def:formResponse | ticketTypeId | string | yes | no | maxLength:300 | No description in lexicon yet. |
| def:formResponse | fieldKey | string | yes | no | maxLength:64 | No description in lexicon yet. |
| def:formResponse | value | string | yes | no | maxLength:2000 | No description in lexicon yet. |
| def:formResponse | showAtCheckIn | boolean | yes | no | none | No description in lexicon yet. |
| def:formResponse | createdAt | string | yes | no | format:datetime | No description in lexicon yet. |

**Declared errors:** `AppNotRegistered` — Caller DID is not registered as an ATM app.; `TicketsModuleDisabled` — This app has not enabled ATM Tickets.; `EventNotFound` — Ticketed event not found.; `EventControlRequired` — A verified primary-organizer or accepted co-organizer authorization is required for this event.; `InvalidCursor` — Ticket form cursor is invalid.; `UserDidMismatch` — organizerAssertionJwt issuer does not match organizerDid.

### tickets.atmosphere.releaseFreeTicket 10 fields

| Location | Field | Type | Required | Nullable | Limits | Description |
| --- | --- | --- | --- | --- | --- | --- |
| input | environment | string<test \| live> | no | no | maxLength:16 | No description in lexicon yet. |
| input | eventId | string | no | no | minLength:1, maxLength:300 | No description in lexicon yet. |
| input | eventUri | string | no | no | format:at-uri | No description in lexicon yet. |
| input | buyerDid | string | yes | no | format:did | No description in lexicon yet. |
| input | buyerAssertionJwt | string | yes | no | maxLength:8192 | Required short-lived user service-auth JWT from buyerDid to ATM, scoped to tickets.atmosphere.releaseFreeTicket. |
| input | idempotencyKey | string | yes | no | minLength:1, maxLength:200 | Caller-stable identity for this release gesture. Reuse the same key after an ambiguous or lost response; ATM replays the original completed result and never releases tickets claimed later. A key cannot be reused for another buyer, event, or ticketIds selector in the same app environment. |
| input | ticketIds | array<string> | no | no | maxLength:50 | Optional narrowing to specific tickets — OMIT the field to release EVERY active free-claim ticket the buyer holds for this event, or pass an EMPTY array (or one with no valid ids) to release NOTHING and get releasedCount 0. The two are deliberately different so an empty client selection cannot un-RSVP a buyer from everything. |
| output | environment | string<test \| live> | yes | no | maxLength:16 | No description in lexicon yet. |
| output | releasedCount | integer | yes | no | minimum:0 | Authoritative number of tickets released — may exceed releasedTicketIds.length, which is capped at 1000, so treat a shorter list as partial and re-query rather than as the complete set. |
| output | releasedTicketIds | array<string> | yes | no | maxLength:1000 | Ids of the released tickets, truncated to the first 1000 — compare against releasedCount to detect truncation. |

**Declared errors:** `AppNotRegistered` — Caller DID is not registered as an ATM app.; `TicketsModuleDisabled` — This app has not enabled ATM Tickets.; `UserAssertionRequired` — A verified buyer assertion (buyerAssertionJwt) is required to release free-claim tickets.; `AuthVerificationFailed` — The service-auth token could not be verified.; `UserDidMismatch` — buyerAssertionJwt issuer does not match buyerDid.; `InvalidRequest` — Provide eventId or eventUri.; `EventNotFound` — The event does not exist for this app and environment.; `IdempotencyConflict` — The idempotencyKey was already used for a different buyer, event, or ticketIds selector.; `TicketsBusy` — The inventory row is contended; retry shortly.

### tickets.atmosphere.releaseTicketHold 6 fields

| Location | Field | Type | Required | Nullable | Limits | Description |
| --- | --- | --- | --- | --- | --- | --- |
| input | environment | string<test \| live> | no | no | maxLength:16 | No description in lexicon yet. |
| input | holdId | string | yes | no | minLength:1, maxLength:300 | No description in lexicon yet. |
| input | reason | string | no | no | maxLength:200 | No description in lexicon yet. |
| output | hold | ref:#hold | yes | no | none | No description in lexicon yet. |
| def:hold | id | string | yes | no | maxLength:300 | No description in lexicon yet. |
| def:hold | status | string<released \| expired \| failed \| completed> | yes | no | maxLength:32 | No description in lexicon yet. |

**Declared errors:** `AppNotRegistered` — Caller DID is not registered as an ATM app.; `TicketsModuleDisabled` — This app has not enabled ATM Tickets.; `TicketHoldNotFound` — Ticket hold not found.

### tickets.atmosphere.revokeCollaboration 5 fields

| Location | Field | Type | Required | Nullable | Limits | Description |
| --- | --- | --- | --- | --- | --- | --- |
| input | environment | string<test \| live> | no | no | maxLength:16 | No description in lexicon yet. |
| input | collaborationId | string | yes | no | minLength:1, maxLength:300 | No description in lexicon yet. |
| input | organizerDid | string | yes | no | format:did | The revoking PRIMARY organizer (or accepted co-organizer) authorizing this revocation via event control. |
| input | organizerAssertionJwt | string | no | no | maxLength:8192 | Optional short-lived user service-auth JWT from organizerDid to ATM, scoped to tickets.atmosphere.revokeCollaboration. |
| output | collaboration | ref:tickets.atmosphere.defs#organizerCollaboration | yes | no | none | No description in lexicon yet. |

**Declared errors:** `AppNotRegistered` — Caller DID is not registered as an ATM app.; `TicketsModuleDisabled` — This app has not enabled ATM Tickets.; `CollaborationNotFound` — Collaboration invitation not found.; `EventNotFound` — Ticketed event not found.; `EventControlRequired` — A verified primary-organizer or accepted co-organizer authorization is required for this event.; `UserDidMismatch` — organizerAssertionJwt issuer does not match organizerDid.

### tickets.atmosphere.setEventCapacity 11 fields

| Location | Field | Type | Required | Nullable | Limits | Description |
| --- | --- | --- | --- | --- | --- | --- |
| input | environment | string<test \| live> | no | no | maxLength:16 | No description in lexicon yet. |
| input | eventId | string | no | no | minLength:1, maxLength:300 | No description in lexicon yet. |
| input | eventUri | string | no | no | format:at-uri | No description in lexicon yet. |
| input | organizerDid | string | no | no | format:did | The current primary organizer authorizing this mutation. Omit only when the calling app is itself that primary organizer. |
| input | organizerAssertionJwt | string | no | no | maxLength:8192 | Optional only for an app updating its own event. Otherwise, a short-lived user service-auth JWT from organizerDid to ATM scoped to tickets.atmosphere.setEventCapacity. |
| input | capacity | integer | no | no | minimum:1, maximum:250000 | Total tickets across ALL ticket types of the event. |
| input | unlimited | boolean | no | no | none | true clears the event capacity (unlimited — the default posture for new events). |
| output | eventId | string | yes | no | maxLength:300 | No description in lexicon yet. |
| output | capacity | integer | no | no | minimum:1, maximum:250000 | The event capacity now in effect. Omitted when unlimited. |
| output | soldQuantity | integer | yes | no | minimum:0 | No description in lexicon yet. |
| output | heldQuantity | integer | yes | no | minimum:0 | No description in lexicon yet. |

**Declared errors:** `AppNotRegistered` — Caller DID is not registered as an ATM app.; `TicketsModuleDisabled` — This app has not enabled ATM Tickets.; `EventNotFound` — Ticketed event not found.; `EventControlRequired` — A verified current primary-organizer authorization is required for this event.; `UserDidMismatch` — organizerAssertionJwt issuer does not match organizerDid.; `InvalidCapacity` — Capacity is invalid, or lower than tickets already sold or held for the event.; `InvalidCapacityConfig` — Provide exactly one of capacity or unlimited:true.

### tickets.atmosphere.setTicketTypeForm 16 fields

| Location | Field | Type | Required | Nullable | Limits | Description |
| --- | --- | --- | --- | --- | --- | --- |
| input | environment | string<test \| live> | no | no | maxLength:16 | No description in lexicon yet. |
| input | ticketTypeId | string | yes | no | minLength:1, maxLength:300 | No description in lexicon yet. |
| input | organizerDid | string | yes | no | format:did | No description in lexicon yet. |
| input | organizerAssertionJwt | string | no | no | maxLength:8192 | Optional short-lived user service-auth JWT from organizerDid to ATM, scoped to tickets.atmosphere.setTicketTypeForm. Proves the app is configuring ticketing with organizer consent. |
| input | form | ref:#form | no | yes | none | No description in lexicon yet. |
| output | ticketTypeId | string | yes | no | maxLength:300 | No description in lexicon yet. |
| output | fieldCount | integer | yes | no | minimum:0 | No description in lexicon yet. |
| def:form | version | integer | yes | no | minimum:1 | Form schema version. Currently 1. |
| def:form | fields | array<ref:#formField> | yes | no | maxLength:30 | No description in lexicon yet. |
| def:formField | key | string | yes | no | minLength:1, maxLength:64 | No description in lexicon yet. |
| def:formField | label | string | yes | no | minLength:1, maxLength:200 | No description in lexicon yet. |
| def:formField | description | string | no | no | maxLength:1000 | Optional buyer-facing help text shown below the question. |
| def:formField | type | string<text \| textarea \| email \| select \| checkbox \| boolean \| number> | yes | no | maxLength:16 | No description in lexicon yet. |
| def:formField | required | boolean | no | no | none | No description in lexicon yet. |
| def:formField | showAtCheckIn | boolean | no | no | none | Show this answer at check-in. Allowed ONLY on select/checkbox/boolean/number fields; rejected on text/textarea/email so no free-text/email answer can reach the door scanner. |
| def:formField | options | array<string> | no | no | maxLength:50 | Choice values for select fields; each string is both the stored value and the display label. Deliberately atomic: richer per-option shapes (value/label pairs) would ship as a NEW optional field rather than mutating these items. |

**Declared errors:** `AppNotRegistered` — Caller DID is not registered as an ATM app.; `TicketsModuleDisabled` — This app has not enabled ATM Tickets.; `TicketTypeNotFound` — Ticket type not found.; `EventNotFound` — Ticketed event not found.; `EventControlRequired` — A verified primary-organizer or accepted co-organizer authorization is required for this event.; `InvalidTicketForm` — The form schema is invalid (e.g. showAtCheckIn set on a free-text or email field).; `UserDidMismatch` — organizerAssertionJwt issuer does not match organizerDid.

### tickets.atmosphere.ticketedEvent 7 fields

| Location | Field | Type | Required | Nullable | Limits | Description |
| --- | --- | --- | --- | --- | --- | --- |
| record | event | ref:com.atproto.repo.strongRef | yes | no | none | CID-pinned strongRef to the canonical public community.lexicon.calendar.event record. |
| record | ticketTypes | array<ref:com.atproto.repo.strongRef> | no | no | maxLength:250 | Display-ordered CID-pinned strongRefs to the ticket types this record publicly advertises. |
| record | title | string | no | no | maxLength:1000, maxGraphemes:100 | No description in lexicon yet. |
| record | description | string | no | no | maxLength:10000, maxGraphemes:1000 | No description in lexicon yet. |
| record | archived | boolean | no | no | none | True when this ticketed-event anchor is archived. Omitted or false means it is active. |
| record | createdAt | string | yes | no | format:datetime | No description in lexicon yet. |
| record | updatedAt | string | no | no | format:datetime | No description in lexicon yet. |

### tickets.atmosphere.ticketType 15 fields

| Location | Field | Type | Required | Nullable | Limits | Description |
| --- | --- | --- | --- | --- | --- | --- |
| record | event | ref:com.atproto.repo.strongRef | yes | no | none | CID-pinned strongRef to the canonical public community.lexicon.calendar.event record. |
| record | title | string | yes | no | minLength:1, maxLength:1000, maxGraphemes:100 | No description in lexicon yet. |
| record | description | string | no | no | maxLength:10000, maxGraphemes:1000 | No description in lexicon yet. |
| record | currency | string | no | no | minLength:3, maxLength:3 | Deprecated display copy retained for readers of early records; canonical pricing belongs on the money.atmosphere.price referenced by defaultPrice. Lowercase currency code. |
| record | unitAmount | integer | no | no | minimum:0 | Deprecated display copy retained for readers of early records; canonical pricing belongs on the money.atmosphere.price referenced by defaultPrice. 0 continues to mark a free ticket type (claimed via tickets.atmosphere.claimFreeTicket, not checkout). |
| record | quantityTotal | integer | no | no | minimum:1, maximum:250000 | Display hint: the type's configured cap. Omitted when uncapped or undisclosed. Authoritative availability always comes from the availability query; capacity is enforced only in private ATM service state. |
| record | maxPerOrder | integer | no | no | minimum:1, maximum:50 | Organizer-configured per-order limit for this ticket type. Apps must still check live ATM availability before checkout. |
| record | product | ref:com.atproto.repo.strongRef | no | no | none | Optional CID-pinned strongRef to the canonical money.atmosphere.product with kind=ticket for this ticket type in the organizer repo. Optional in the record so free/RSVP ticket types stay a single record, but tickets.atmosphere.createTicketType requires it for a PAID type. When present the Product owns catalog presentation and points at the current immutable money.atmosphere.price; checkout still lists on this ticketType record URI, never on the Product or the price. |
| record | defaultPrice | ref:com.atproto.repo.strongRef | no | no | none | Optional CID-pinned strongRef to the current money.atmosphere.price for this ticket type in the organizer repo. Legacy direct pricing retained for readers of records written before ticket types could carry a Product: when product is present, economics resolve through that Product's current defaultPrice and this field is not additionally authoritative. Absent means the type is published without catalog pricing; ATM private configuration remains settlement truth. Checkout always lists on this ticketType record URI, never on the price. |
| record | saleStartsAt | string | no | no | format:datetime | No description in lexicon yet. |
| record | saleEndsAt | string | no | no | format:datetime | No description in lexicon yet. |
| record | archived | boolean | no | no | none | True when this ticket type is archived. Omitted or false means it is not archived. |
| record | archivedAt | string | no | no | format:datetime | No description in lexicon yet. |
| record | createdAt | string | yes | no | format:datetime | No description in lexicon yet. |
| record | updatedAt | string | no | no | format:datetime | No description in lexicon yet. |

### tickets.atmosphere.updateTicketEvent 11 fields

| Location | Field | Type | Required | Nullable | Limits | Description |
| --- | --- | --- | --- | --- | --- | --- |
| input | environment | string<test \| live> | no | no | maxLength:16 | No description in lexicon yet. |
| input | eventId | string | yes | no | minLength:1, maxLength:300 | No description in lexicon yet. |
| input | organizerDid | string | no | no | format:did | The primary organizer or accepted co-organizer authorizing this mutation. Omit only when the calling app is itself the event's primary organizer. |
| input | organizerAssertionJwt | string | no | no | maxLength:8192 | Optional only for an app updating its own event. Otherwise, a short-lived user service-auth JWT from organizerDid to ATM scoped to tickets.atmosphere.updateTicketEvent. |
| input | title | string | no | no | minLength:1, maxLength:3000, maxGraphemes:300 | No description in lexicon yet. |
| input | startsAt | string | no | yes | format:datetime | No description in lexicon yet. |
| input | eventCid | string | no | yes | format:cid | No description in lexicon yet. |
| input | imageUrl | string | no | yes | format:uri | No description in lexicon yet. |
| input | status | string<active \| paused \| archived> | no | no | maxLength:32 | ATM ticket-sales lifecycle state. It does not control visibility of the public event record. |
| input | metadata | unknown | no | no | none | No description in lexicon yet. |
| output | event | ref:tickets.atmosphere.defs#eventSummary | yes | no | none | No description in lexicon yet. |

**Declared errors:** `AppNotRegistered` — Caller DID is not registered as an ATM app.; `TicketsModuleDisabled` — This app has not enabled ATM Tickets.; `TicketEventNotFound` — Ticketed event config not found.; `EventControlRequired` — A verified primary-organizer or accepted co-organizer authorization is required for this event.; `PrimaryOrganizerRequired` — Only the current primary organizer can archive the event.; `UserDidMismatch` — organizerAssertionJwt issuer does not match organizerDid.

### tickets.atmosphere.updateTicketType 20 fields

| Location | Field | Type | Required | Nullable | Limits | Description |
| --- | --- | --- | --- | --- | --- | --- |
| input | environment | string<test \| live> | no | no | maxLength:16 | No description in lexicon yet. |
| input | ticketTypeId | string | yes | no | minLength:1, maxLength:300 | No description in lexicon yet. |
| input | organizerDid | string | no | no | format:did | The primary organizer or accepted co-organizer authorizing this mutation. Omit only when the calling app is itself the event's primary organizer. |
| input | organizerAssertionJwt | string | no | no | maxLength:8192 | Optional only for an app updating its own event. Otherwise, a short-lived user service-auth JWT from organizerDid to ATM scoped to tickets.atmosphere.updateTicketType. |
| input | title | string | no | no | minLength:1, maxLength:1000, maxGraphemes:100 | No description in lexicon yet. |
| input | description | string | no | yes | maxLength:10000, maxGraphemes:1000 | No description in lexicon yet. |
| input | currency | string | no | no | minLength:3, maxLength:3 | Lowercase ISO 4217 alphabetic code matching money.atmosphere.price. Chargeability is enforced separately by the configured processor allowlist. Asset-denominated value uses the money.atmosphere.payment.defs value union, never this field. |
| input | unitAmount | integer | no | no | minimum:0, maximum:2000000 | Amount in the smallest unit of currency. 0 creates a free ticket type (claimed via tickets.atmosphere.claimFreeTicket). A resulting paid ticket type must have an exact organizer-owned kind=ticket Product; paid amounts must also meet the processor minimum charge. |
| input | maxPerOrder | integer | no | no | minimum:1, maximum:50 | No description in lexicon yet. |
| input | saleStartsAt | string | no | yes | format:datetime | No description in lexicon yet. |
| input | saleEndsAt | string | no | yes | format:datetime | No description in lexicon yet. |
| input | ticketTypeRef | ref:com.atproto.repo.strongRef | no | yes | none | No description in lexicon yet. |
| input | product | ref:com.atproto.repo.strongRef | no | no | none | Exact current organizer-owned money.atmosphere.product with kind=ticket. createTicketType requires it whenever unitAmount is greater than 0; a free type may omit it. updateTicketType requires the resulting paid type to retain or receive one, may attach or repoint it, and cannot clear it. The Product must be active and its exact default Price must be one-time, per-unit, and match the ticket amount and currency. |
| input | defaultPrice | ref:com.atproto.repo.strongRef | no | yes | none | Legacy direct-Price compatibility only. New callers using product MUST omit defaultPrice; ATM derives and verifies Product.defaultPrice and rejects both fields together. Readers still accept this field on Product-less historical ticket types. |
| input | metadata | unknown | no | no | none | No description in lexicon yet. |
| input | visibility | string<public \| hidden> | no | no | maxLength:16 | Private buyer-facing visibility (default public). Hidden types are excluded from availability and buyer surfaces until unlocked by a ticket access code; organizer surfaces always see them. |
| input | quantityTotal | integer | no | no | minimum:1, maximum:250000 | Set the per-type cap. |
| input | unlimited | boolean | no | no | none | true clears the per-type cap (unlimited). |
| input | status | string<active \| paused \| archived> | no | no | maxLength:32 | No description in lexicon yet. |
| output | ticketType | ref:tickets.atmosphere.defs#ticketTypeSummary | yes | no | none | No description in lexicon yet. |

**Declared errors:** `AppNotRegistered` — Caller DID is not registered as an ATM app.; `TicketsModuleDisabled` — This app has not enabled ATM Tickets.; `RecipientNotPayable` — The organizer has not completed payment setup for this environment.; `RecipientCurrencyUnavailable` — ATM could not verify the organizer's primary settlement currency.; `RecipientCurrencyUnsupported` — The organizer's primary settlement currency is not supported by ATM's current payment processor.; `RecipientCurrencyNotEnabled` — The organizer's primary settlement currency is not enabled in this ATM environment.; `RecipientCurrencyMismatch` — The paid ticket currency does not match the organizer's primary settlement currency.; `UnsupportedHistoricalCurrency` — Stored ticket data uses a historical currency that the current ISO 4217 wire contract cannot represent.; `TicketTypeNotFound` — Ticket type not found.; `EventControlRequired` — A verified primary-organizer or accepted co-organizer authorization is required for this event.; `PrimaryOrganizerRequired` — Only the current primary organizer can change ticket pricing, capacity, or raw metadata, or archive the ticket type.; `UserDidMismatch` — organizerAssertionJwt issuer does not match organizerDid.; `InvalidAmount` — Ticket price is invalid: negative, above the maximum, or a paid amount below the processor minimum charge (use 0 for free ticket types).; `TicketCurrencyUnsupportedForFee` — This paid ticket currency is incompatible with the app's fixed ticket-fee denomination.; `InvalidCapacity` — Capacity is invalid, or lower than tickets already sold or held for this type.; `InvalidCapacityConfig` — Provide at most one of quantityTotal or unlimited:true.

### tickets.atmosphere.verifyTicket 8 fields

| Location | Field | Type | Required | Nullable | Limits | Description |
| --- | --- | --- | --- | --- | --- | --- |
| input | environment | string<test \| live> | no | no | maxLength:16 | No description in lexicon yet. |
| input | ticketToken | string | yes | no | minLength:1, maxLength:4000 | No description in lexicon yet. |
| output | valid | boolean | yes | no | none | No description in lexicon yet. |
| output | reason | string | no | no | maxLength:100 | No description in lexicon yet. |
| output | ticket | ref:tickets.atmosphere.defs#issuedTicket | no | no | none | No description in lexicon yet. |
| output | presentation | ref:tickets.atmosphere.defs#ticketPresentation | no | no | none | No description in lexicon yet. |
| output | event | ref:tickets.atmosphere.defs#eventSummary | no | no | none | No description in lexicon yet. |
| output | ticketType | ref:tickets.atmosphere.defs#ticketTypeSummary | no | no | none | No description in lexicon yet. |

**Declared errors:** `AppNotRegistered` — Caller DID is not registered as an ATM app.; `TicketsModuleDisabled` — This app has not enabled ATM Tickets.; `TicketNotFound` — Ticket not found or verification failed.; `UnsupportedHistoricalCurrency` — Stored ticket data uses a historical currency that the current ISO 4217 wire contract cannot represent.

## Contract tests

Tickets docs are checked against `lexicons/tickets/atmosphere`. Regenerate the reference after lexicon edits and run the contract check before sharing docs with app developers.

```
node scripts/generate-docs-reference.mjs
node scripts/check-docs-contracts.mjs
node scripts/check-examples.mjs
```

- Every tickets.atmosphere NSID appears in docs.html and docs/generated-reference.json.
- Real docs pages are generated for overview, build, callbacks, reference, and operations.
- API examples document auth mode, request shape, and common failure behavior.
- Example server files include typecheck and smoke scripts for copied starter-kit code.

## API reference examples

Use [current request examples](https://atmosphere.tickets/docs-build.html#api-examples) for paid holds, fresh free claims and app-authorized check-in. Exact fields and errors are generated above from ATM. Query ticket lists use `buyer`/`organizer`; private assertion-bearing list procedures use POST bodies.

## XRPC methods

Use service calls for private inventory and ticket operations. ATM remains responsible for checkout initiation, settlement, receipts, app fees, and payment proofs.

```
POST tickets.atmosphere.createTicketEvent
POST tickets.atmosphere.updateTicketEvent
POST tickets.atmosphere.cancelTicketEvent
POST tickets.atmosphere.createTicketType
POST tickets.atmosphere.updateTicketType
POST tickets.atmosphere.archiveTicketType
POST tickets.atmosphere.setEventCapacity
POST tickets.atmosphere.setTicketTypeForm
GET  tickets.atmosphere.getTicketAvailability
POST tickets.atmosphere.createTicketHold
POST tickets.atmosphere.releaseTicketHold
POST tickets.atmosphere.claimFreeTicket
POST tickets.atmosphere.releaseFreeTicket
POST tickets.atmosphere.joinWaitlist
POST tickets.atmosphere.claimWaitlistOffer
POST tickets.atmosphere.listEventWaitlist
POST tickets.atmosphere.listTicketFormResponses
POST tickets.atmosphere.inviteOrganizerCollaboration
POST tickets.atmosphere.acceptCollaboration
POST tickets.atmosphere.listCollaborations
POST tickets.atmosphere.revokeCollaboration
GET  tickets.atmosphere.listBuyerTickets
GET  tickets.atmosphere.listOrganizerTickets
POST tickets.atmosphere.verifyTicket
POST tickets.atmosphere.checkInTicket
GET  tickets.atmosphere.listPublicConfig (public AppView)
```

## Error codes

The per-method generated field panels include declared errors from the copied schemas. Handle actual structured errors and check-in statuses instead of inventing exception names from UI messages.

| InsufficientTicketCapacity / TicketsUnavailable | Refresh availability and selection; do not start checkout without a successful hold. |
| --- | --- |
| FreeTicketRequiresClaim / PaidTicketRequiresCheckout | Choose the zero-price claim path or paid checkout path as required by the configured type. |
| InvalidBuyerIdentity / UserAssertionRequired / AuthVerificationFailed | Supply the correct paired buyer fields and a fresh method-scoped assertion. |
| CustomerEmailRequired / InvalidCustomerEmail | Collect valid private delivery email before a fresh free claim. |
| EventControlRequired / PrimaryOrganizerRequired | Revalidate current organizer authority; app provenance is insufficient. |
| IdempotencyKeyInFlight / IdempotencyKeyConflict / IdempotencyConflict | Wait/retry the original exact operation when in flight; resolve conflicting bodies before another request. |
| CheckoutPayerChanged | Reconcile the final buyer and original private status capability; do not blindly create another sale. |
| TicketNotFound / CheckInListMismatch | Reject invalid or out-of-scope admission. Repeat scans are a normal `already-checked-in` result. |
| TicketsBusy | Retry with bounded backoff using the same operation key. |

## Error recovery

1. Capacity conflict: refresh authoritative availability and quantity.
2. Invalid assertion: mint a fresh assertion for the required method. Do not silently drop an asserted buyer into a new guest purchase.
3. Uncertain hold/payment: retain the original operation key and status capability until reconciled.
4. Failed callback: repair verification/processing, then redrive the durable delivery.
5. Repeat scan: show the original `already-checked-in` timestamp.

## Security model

| Public | Community event/RSVP records, ticketType/ticketedEvent/checkInList catalog, and policy-gated payment proofs. |
| --- | --- |
| Private | Capacity enforcement, holds, issued tickets, attendee/contact data, codes/counters, staff grants, pass secrets, check-ins and lifecycle audit. |
| App scope | Calling app, environment, module policy and current organizer selling/control authority determine access. |
| User assertions | Prove private action identity/intent; grant no public repo write. |
| Presentation and admission | Current moderation can suppress displayed content while the issued entitlement and authorized admission remain valid. |

## Threat model

| Threat | Risk | Primary control |
| --- | --- | --- |
| Oversell | Concurrent buyers exceed capacity. | Private transactional holds and issued-ticket rows. |
| Buyer spoofing | App lies about buyer DID. | Short-lived buyer assertion with aud/lxm/jti checks. |
| Replay | Duplicate webhook or claim mutates twice. | Delivery ids and idempotency keys before side effects. |
| QR leakage | Ticket or buyer data leaks from passes. | Opaque scan tokens only; hash secrets privately. |
| Visibility creep | Apps see unrelated payment or attendee data. | App-scoped events, dashboards, and module permissions. |

## Security diagrams

01

### App service-auth

App DID mints a short-lived token for an exact Tickets method; ATM verifies issuer, audience, lxm, expiry, signature, and jti.

02

### Organizer assertion

Organizer authorizes the event app to configure ticket types and capacity for a specific event context.

03

### Buyer assertion

Buyer DID assertion binds a signed-in event-app buyer to a hold or free claim without forcing checkout re-auth.

04

### QR verification

Opaque token is checked against private issued-ticket state; check-in mutates once and repeat scans return existing state.

05

### Private/public boundary

Public event and type refs are display/catalog only; holds, issued tickets, scan tokens, attendee answers, and check-ins stay private.

## Compliance boundaries

ATM owns payment processing and processor coordination. Event apps own event UX and app-specific fulfillment. Tickets owns scarce ticket truth. Keep those boundaries visible in support, dashboards, and app developer docs.

| Actor | Can see | Must not see |
| --- | --- | --- |
| Event app | Payments it originated, app fee data, ticket/order status needed for fulfillment. | Organizer KYC, bank details, connected-account ids, or other-app payments. |
| Organizer | Ticket sales, payouts, disputes, taxes, attendee data needed for the event. | App secrets, app webhook signatures, unrelated app fee routing. |
| Scanner | Opaque token status, event/type display, check-in result. | Buyer email, payment id, processor id, raw QR secrets. |
| Public protocol | Safe event, type, ticketed-event and payment proof refs. | Attendee answers, exact counters, check-in logs, customer PII, fraud/risk state. |

## Data ownership

| Events | Community event records and app UX; current event presentation can change without rewriting purchase history. |
| --- | --- |
| Catalog | Public ticketType/ticketedEvent/checkInList records plus exact attached Product/default Price refs. |
| Inventory | Private transactional type/event pools and hold/issued counters. |
| Buyer data | Private ticket answers, delivery email, assertions and attendee identity. |
| Payments | ATM ledger plus policy-gated public proofs. Free claims have no payment row; paid-with-Free-coupon orders have $0 rows and no public proof. |
| Admission | Private revocable pass tokens, ticket status, scanner grants and check-in audit. |

## Feature map

Atmosphere Tickets can support Hi.Events-style capabilities, but the ownership split should stay sharp: centralized only where ticketing correctness requires it, public/on-protocol where portability helps, and app-owned where UX differs.

| Capability | Owner | Notes |
| --- | --- | --- |
| Ticket types and capacity | Tickets | Scarce inventory must be transactional and enforced by ATM for authorized seller channels. |
| Promo codes and private codes | Tickets + ATM | Private code configuration can be portable; redemption counters stay private. |
| Event SEO and discovery | Event apps | Apps own social discovery, event pages, and product-specific presentation. |
| Organizer dashboard | Event apps + ATM | Event-specific tools in apps, money/payment controls in ATM. |
| Order management | Tickets + apps | Ticket status in Tickets; attendee messaging and presentation in apps. |
| Analytics | ATM + apps | Money ledger in ATM, traffic/social/product analytics in the app. |
| Affiliate/campaign UX | Apps | Supported catalog refs can connect back to Tickets/ATM for redemption truth. |

## Lexicon review

Review current record portability and service boundaries: optional catalog refs for free types, exact Product/default Price economics for paid types, private type/event capacity, organizer control independent of app provenance, and assertions kept in POST bodies. Compare the exact copied ATM revision before proposing schema edits.

Use the raw JSON and generated error/field tables. A docs bundle is not proof that namespace publication, runtime deployment or release approval has occurred.

## Public review bundle

Share the raw lexicons, generated reference, threat model, integration flow, and open questions when asking the AT Protocol community to review Tickets contracts.

Raw contracts

### lexicons/tickets/atmosphere

Record and XRPC schemas for event/type catalog, event capacity, holds, claims, free release, availability and check-in.

Generated reference

### docs/generated-reference.json

Machine-readable index for docs and review tools.

Review questions

### Privacy and interoperability

Check public/private boundaries, app/user auth, and whether another event app can integrate without private assumptions.

After review

### Regenerate docs

Update ATM canonical source, copy generated schemas, regenerate reference, run checks, and record feedback-driven changes.

## Glossary

| Event app | The app that owns public event pages, discovery, organizer UX, buyer UX, and scanner screens. |
| --- | --- |
| Organizer | The user or project receiving ticket revenue and configuring ticketing for an event. |
| Repo | A user's public AT Protocol repository of signed records, such as event or ticket metadata records. |
| PDS | Personal Data Server: the service that hosts a user's account and repo. |
| Service-auth | AT Protocol Inter-Service Authentication: a short-lived JWT scoped to one XRPC method. |
| Ticket type | A sellable or claimable ticket type for an event. |
| Capacity pool | A private inventory bucket that one or more ticket types can share. |
| Hold | A short-lived transactional reservation before checkout or free claim completion. |
| Issued ticket | The private ticket truth created after payment confirmation or free claim success. |
| Buyer assertion | A short-lived user service-auth JWT proving the app saw this buyer for this action. |
| Organizer assertion | A short-lived user service-auth JWT proving the organizer authorized ticket configuration. |
| Scan token | An opaque private token embedded in a QR code, wallet pass, or scan URL. |
| Check-in list | The scanner context for verifying and recording entry. |

[PreviousCallbacks](https://atmosphere.tickets/docs-callbacks.html) [Next pageOperations](https://atmosphere.tickets/docs-operations.html)
