Skip to main content
The access control system manages physical entry and exit at event venues. It operates on two entity types — tickets (sold to attendees) and credentials (issued to staff and VIPs) — and tracks each through a ledger and a pair of boolean flags: access_status and access_entry.
FlagMeaning
access_status: false, access_entry: falseNever scanned — ticket is unseen at the gate
access_status: true, access_entry: trueCurrently inside the venue
access_status: true, access_entry: falseWas inside, has exited
Access control functions only act on tickets where status = false (sold tickets). A ticket that has not been sold cannot be scanned for entry.

List Checkpoints

events_list_checkpoints returns all active checkpoint assignments for a collaborator. Checkpoints are stored as sub-documents of the collaborator in u_collaborators/{userd_id}/checkpoints.
POST /events_list_checkpoints
Content-Type: application/json
{
  "data": {
    "userd_id": "collab_uid_001"
  }
}
data.userd_id
string
required
The UID of the collaborator (checkpoint operator). Filters checkpoints with status of "Activo" or "En Progreso".

Response Fields

data.eventos
array
Array of checkpoint objects.
data.eventos[].event_id
string
The Firestore document ID (used as key) for this checkpoint.
data.eventos[].name
string
Display name of the checkpoint (e.g. "Entrada Principal").
data.eventos[].type
string
Checkpoint type identifier.
data.eventos[].status
string
"Activo" or "En Progreso".
data.eventos[].date_start
Timestamp
When this checkpoint assignment begins.
data.eventos[].date_end
Timestamp
When this checkpoint assignment ends.
data.eventos[].event
object
Media metadata for the associated event (sourced from data.event.media).
Success (200)
{
  "message": "Eventos encontrados",
  "status": 200,
  "data": {
    "valido": true,
    "eventos": [
      {
        "event_id": "JAOTIiQrtU1fMWZZY2IZ",
        "name": "Entrada Principal",
        "type": "entry",
        "status": "Activo",
        "date_start": "2024-11-15T17:00:00.000Z",
        "date_end": "2024-11-15T22:00:00.000Z",
        "event": { "banner": "https://cdn.example.com/banner.jpg" }
      }
    ]
  }
}

List Credentials

events_list_credentials returns all active credentials for an event from events/{event_id}/credentials.
POST /events_list_credentials
Content-Type: application/json
{
  "data": {
    "event_id": "JAOTIiQrtU1fMWZZY2IZ"
  }
}
data.event_id
string
required
The event to list credentials for. Only documents with status: true are returned.

Response Fields

data.credenciales
array
Array of active credential objects.
data.credenciales[].id
string
Firestore document ID of the credential.
data.credenciales[].name
string
Credential display name.
data.credenciales[].holder
string
Name of the person holding this credential.
data.credenciales[].description
string
Description or role notes for the credential.
data.credenciales[].status
boolean
true — only active credentials are returned.
data.credenciales[].date_created
Timestamp
When the credential was created (data.date.created).
data.credenciales[].date_updated
Timestamp
When the credential was last updated (data.date.updated).

Ticket Access Control Flow

1

Scan ticket QR at entry gate

The gate app calls tickets_access_control_in with the scanned ticket_id.
2

Look up ticket in PostgreSQL

The function queries tickets for ticket_id = ? AND status = false. A ticket that has not been sold (status = true) is rejected with "Ticket no valido".
3

Evaluate current access state

Three cases are handled based on access_status and access_entry:
  • Both false → First entry. Sets access_status = true, access_entry = true, appends accessed to ledger.
  • access_status = true, access_entry = false → Re-entry after previous exit. Sets access_entry = true only.
  • Both true → Already inside. Returns error "Ticket ya Utilizado no puede volver Ingresar".
4

Write updates

Changes are written to Firestore (events/{eventId}/tickets/{docId}) and PostgreSQL (tickets) simultaneously.
5

Exit scan

When the holder leaves, tickets_access_control_out is called. It sets access_entry = false and appends a came-out ledger entry.

Ticket Entry

tickets_access_control_in
POST /tickets_access_control_in
Content-Type: application/json
{
  "data": {
    "ticket_id": "JAOTIiQrtU1fMWZZY2IZ-nGxHQ00YzCg9PphEwlYb"
  }
}
data.ticket_id
string
required
The full composite ticket ID to scan for entry.
ScenarioResponse messagevalido
First entry"Ticket Ingresando"true
Re-entry after exit"Ticket ReIngreso"true
Already inside"Ticket ya Utilizado no puede volver Ingresar"false
Not a sold ticket"Ticket no valido"false

Ticket Exit

tickets_access_control_out
POST /tickets_access_control_out
Content-Type: application/json
{
  "data": {
    "ticket_id": "JAOTIiQrtU1fMWZZY2IZ-nGxHQ00YzCg9PphEwlYb"
  }
}
data.ticket_id
string
required
The full composite ticket ID to scan for exit.
ScenarioResponse messagevalido
Valid exit"Ticket Salida"true
Never entered"Ticket no Ingreso no puede salir"false
Not a sold ticket"Ticket no valido"false

Credential Entry

credentials_access_control_in handles entry for staff/VIP credentials stored in Firestore. Unlike tickets, credentials do not use PostgreSQL — all state is managed directly in events/{event_id}/credentials/{credential_id}.
POST /credentials_access_control_in
Content-Type: application/json
{
  "data": {
    "event_id": "JAOTIiQrtU1fMWZZY2IZ",
    "credential_id": "cred_doc_001"
  }
}
data.event_id
string
required
The event the credential belongs to.
data.credential_id
string
required
The Firestore document ID of the credential to scan.
ScenarioResponse messagevalido
First entry"Credencial valida Ingresando"true
Re-entry"Credencial valida Re-Ingresando"true
Already inside"Credencial ya Entro"false
Not found"Credencial no valida"false

Credential Exit

credentials_access_control_out
POST /credentials_access_control_out
Content-Type: application/json
{
  "data": {
    "event_id": "JAOTIiQrtU1fMWZZY2IZ",
    "credential_id": "cred_doc_001"
  }
}
data.event_id
string
required
The event the credential belongs to.
data.credential_id
string
required
The Firestore document ID of the credential to scan for exit.
ScenarioResponse messagevalido
Valid exit"Credencial valida Saliendo"true
Never entered"Credencial NO Entro"false
Not found"Credencial no valida"false

Cold (Offline) Sync

tickets_access_control_cold synchronises a batch of entry/exit events that were captured by a gate device operating without connectivity. All events in the batch are applied in order and deduplicated by ticket_id — only the first occurrence of each ticket in the array is processed.
POST /tickets_access_control_cold
Content-Type: application/json
{
  "data": {
    "tickets_cold": [
      {
        "ticket_id": "JAOTIiQrtU1fMWZZY2IZ-nGxHQ00YzCg9PphEwlYb",
        "date": "2024-11-15T20:14:00-05:00",
        "tipo": "in"
      },
      {
        "ticket_id": "JAOTIiQrtU1fMWZZY2IZ-LqQTJHAGEkdwzrbcScWe",
        "date": "2024-11-15T20:22:00-05:00",
        "tipo": "out"
      }
    ]
  }
}
data.tickets_cold
array
required
Array of cold-sync entries. Each object must include ticket_id, date, and tipo.
data.tickets_cold[].ticket_id
string
required
The composite ticket ID that was scanned offline.
data.tickets_cold[].date
string
required
ISO 8601 timestamp of when the scan occurred on the offline device.
data.tickets_cold[].tipo
string
required
"in" for entry (writes accessed to ledger, sets access_entry = true) or "out" for exit (writes came-out, sets access_entry = false).
Duplicate ticket_id entries in tickets_cold are silently deduplicated. Only the first occurrence for each ticket is processed. Sort your payload chronologically before sending.
Success (200)
{
  "message": "Tickets Frios Sincronizados",
  "status": 200,
  "data": {
    "valido": true,
    "message": "Tickets Frios Sincronizados"
  }
}

Build docs developers (and LLMs) love