Ir al artículo
Aniq-UI

TicketoryReferencia de la API

Referencia de la API

Cada ruta que sirve la API, quién puede llamarla, y cómo funcionan el inicio de sesión, los permisos, los espacios de trabajo, las reservas, los pagos, los errores, las listas y los límites.

Para el paquete Full Stack

URL base y formato de respuesta

Cada ruta se sirve bajo el prefijo /api. En local, la URL base es http://localhost:8000/api. En un servidor es la dirección de tu API seguida de /api, el mismo valor que leen ambos frontends en NEXT_PUBLIC_API_BASE_URL (Variables de entorno). Las imágenes se sirven fuera del prefijo, en /media/….

Las rutas del sitio web son públicas o aceptan el token de un asistente; las del panel necesitan el token bearer de un miembro del personal, y la mayoría también un permiso. Los cuerpos de las peticiones son JSON, salvo las subidas de archivos. Cada respuesta llega en el mismo sobre:

Envoltorio
{
  "success": true,
  "data": { },
  "message": ""
}

data contiene el resultado. message es una frase corta que rellenan algunas escrituras, en el idioma de la petición, y vacío en los demás casos. El dinero es un número entero de unidades menores con su currency (price_minor: 2000 son 20,00), y cada fecha es una cadena ISO en UTC; cada evento lleva además su time_zone.

La comprobación de estado no necesita token:

Terminal
curl http://localhost:8000/api/health
Respuesta
{"success":true,"data":{"status":"ok","database":"up"},"message":""}

Cuando no se puede leer la base de datos, sigue respondiendo 200, con "status":"degraded" y "database":"down". La comprobación de estado de la imagen de Docker lee ese campo.

Errores

Un fallo mantiene el envoltorio, con success: false y el estado HTTP:

Error
{
  "success": false,
  "data": null,
  "message": "…",
  "errors": { "email": ["…"] },
  "code": "SEAT_UNAVAILABLE",
  "details": { "seats": ["A12"] }
}
  • message es una frase en el idioma de la petición.
  • errors aparece en un fallo de validación, con los problemas por campo, indexados por la ruta que envió el cliente (como title.en o attendee.email).
  • Un campo desconocido en un cuerpo se rechaza con 400, y errors lo nombra. El registro, por ejemplo, acepta solo los campos listados abajo.
  • code y details aparecen cuando una pantalla reacciona a un rechazo concreto: SEAT_UNAVAILABLE con los asientos tomados, HOLD_EXPIRED, SOLD_OUT, ALREADY_ADMITTED con la primera admisión, VERSION_CONFLICT, NOT_READY con lo que falta, COOLDOWN con retry_after en segundos.
  • Una ruta protegida sin token, o con uno caducado, responde 401; un token sin el permiso responde 403.
  • Una petición que supera un límite responde 429.

Cabeceras

EncabezadoSe envía conQué lleva
Authorization: Bearer …Rutas del personal y de asistentesEl token de POST /api/auth/login (personal) o POST /api/customer-auth/login (asistente). Los dos tipos no son intercambiables
X-Workspace-IdRutas del personalEl espacio de trabajo al que se dirige la petición. Uno al que el miembro no pertenece se ignora y se usa el propio
X-Hold-TokenUna reserva y el pago hecho desde ellaEl secreto de la reserva, devuelto una sola vez cuando se crea la reserva
X-Order-TokenRutas de pedidos de un invitadoEl secreto del pedido, devuelto una sola vez por POST /api/checkout. Los pedidos propios de un asistente con sesión iniciada solo necesitan su token
Idempotency-KeyPOST /api/holds, POST /api/checkout, POST /api/admin/orders/:reference/refundsUn UUID creado cuando se abre el formulario. Un reintento con la misma clave y el mismo cuerpo devuelve la primera respuesta en lugar de hacer el trabajo dos veces; sin ella, la petición se rechaza
Accept-LanguageCualquier rutaar para mensajes en árabe; cualquier otro valor responde en inglés

Los textos de eventos, recintos y tipos de entrada llevan ambos idiomas como { "en": "…", "ar": "…" } diga lo que diga Accept-Language, y el cliente elige uno, recurriendo al inglés cuando el árabe está vacío.

Listas y paginación

Una lista
{ "data": [ ], "page": 1, "limit": 10, "total": 36, "totalPages": 4 }
  • La mayoría de las listas se paginan con page y limit, con un máximo de 100 por página: 9 eventos por página en el sitio web, y por defecto 10 eventos, recintos y asistentes y 8 pedidos en el panel. Varias devuelven además counts por pestaña o estado.
  • Las listas de equipo, roles y ajustes del sitio se paginan con page y page_count, y las consultas con page y page_size (10 por defecto, como máximo 50).
  • Las listas del panel llegan con los actualizados más recientemente primero, con el id como desempate, así que la paginación es estable. El catálogo del sitio web llega con lo más cercano primero.
  • Los filtros de la lista del equipo (email, name, phone) se combinan: una fila debe coincidir con todos los dados. name coincide con el nombre, el apellido, el nombre de usuario o el nombre completo.

Inicio de sesión

  1. Iniciar sesión como miembro del personal

    Terminal
    curl -X POST http://localhost:8000/api/auth/login \
      -H "Content-Type: application/json" \
      -d '{"email":"YOUR_EMAIL","password":"YOUR_PASSWORD"}'

    Usa una de las cuentas del panel de Instalación, o la tuya. data.access_token es el token, con token_type Bearer y el miembro del personal con sus roles y permisos. El token dura JWT_EXPIRATION, 7d por defecto, y expires_in informa de ese valor tal como está escrito. GET /api/auth/me devuelve al miembro del personal con sesión iniciada con sus roles y permisos.

  2. Llama a una ruta protegida

    Terminal
    curl http://localhost:8000/api/admin/orders \
      -H "Authorization: Bearer YOUR_TOKEN" \
      -H "X-Workspace-Id: 1"
  • Un correo desconocido y una contraseña incorrecta responden ambos 401 con el mismo mensaje.
  • Diez inicios de sesión fallidos desde una misma dirección en 15 minutos responden 429 hasta que el fallo más antiguo cumple 15 minutos (RATE_LIMIT_LOGIN). Los inicios de sesión correctos no se cuentan. Los inicios de sesión del personal y de los asistentes se cuentan por separado.
  • Las cuentas del personal vienen de los datos de ejemplo o de la página Team; no hay registro de personal. Un cliente cierra sesión olvidando su token.
  • GET /api/admin/workspace/memberships lista los espacios de trabajo a los que pertenece el miembro, los suyos primero. Envía el id del elegido como X-Workspace-Id.
MétodoRutaQuién puede llamarlaQué hace
POST/api/auth/loginCualquieraInicio de sesión del personal: email, password
GET/api/auth/meCualquier miembro del personal con sesión iniciadaEl miembro del personal con sesión iniciada, sus roles y permisos
GET/api/admin/workspace/membershipsCualquier miembro del personal con sesión iniciadaLos espacios de trabajo del miembro, para el selector de la barra de navegación

Permisos

Las rutas del personal comprueban un permiso llamado <area>.<action>. Un miembro tiene todos los permisos de todos los roles que posee, y el rol es el mismo en cada espacio de trabajo al que pertenece. Los 29 permisos y los cuatro roles de ejemplo (Owner, Manager, Finance, Check-in) están listados en Equipo, roles y espacios de trabajo.

Eventos, recintos y organizadores en el sitio web

MétodoRutaQuién puede llamarlaQué hace
GET/api/public/eventsCualquieraEventos públicos próximos, los más cercanos primero. q (título, resumen, recinto, ciudad u organizador), category, city, venue y organiser (slugs), from y to (YYYY-MM-DD), page, limit. Los borradores, los eventos no listados y los eventos que han terminado se dejan fuera
GET/api/public/events/citiesCualquieraLas ciudades con eventos próximos y cuántos tiene cada una, para el filtro de ciudad
GET/api/public/events/:slugCualquieraUn evento completo: descripción, agenda, el recinto con su dirección, accesibilidad, transporte y ubicación, el código de sesión, y los tipos de entrada con precio, comisión, plazas restantes y el límite por pedido. Un evento cancelado responde con status: cancelled
GET/api/public/sessions/:code/availabilityCualquieraDisponibilidad en vivo para el mapa de asientos: el reloj del servidor, hold_seconds, max_per_order, la comisión, los tipos de entrada, el plano de asientos publicado (o null para entrada general) y cada asiento como available, held, sold o unavailable
GET/api/public/categoriesCualquieraLas categorías de eventos
GET/api/public/organisersCualquieraLos organizadores
GET/api/public/organisers/:slugCualquieraUn organizador con hasta 24 de sus próximos eventos y su total
GET/api/public/venuesCualquieraLos recintos, con sus próximos eventos y sus asientos
GET/api/public/venues/:slugCualquieraUn recinto, con su plano de asientos publicado
GET/api/public/settingsCualquieraLo que el sitio web necesita para poner precio y hora a una compra: el nombre del espacio de trabajo, currency, fee_bps (la comisión de reserva que paga el asistente en cada entrada, 300 es un 3 %), hold_seconds, max_per_order, time_zone, support_email, payment_methods y mail_simulated (verdadero mientras los correos se escriben en el registro de la API)
GET/api/settings/publicCualquieraEl site_name, contact_email y contact_city del sitio

Los ingresos del organizador nunca forman parte de una respuesta pública.

Cuentas de asistentes

MétodoRutaQuién puede llamarlaQué hace
POST/api/customer-auth/registerCualquieraRegistro: first_name, last_name, email, password (de 8 a 72 caracteres con una letra y un dígito), terms_accepted (true), y opcionalmente role (attendee u organiser, nunca se lee). Cualquier otro campo responde 400 nombrándolo. Responde 201, con sesión iniciada al instante, y envía un código de seis dígitos
POST/api/customer-auth/loginCualquieraInicio de sesión del asistente: email, password, y remember para un token de 30 días en lugar de uno de un día
POST/api/customer-auth/logoutCualquieraResponde { signed_out: true }; los tokens no guardan estado, así que el cliente olvida su copia
POST/api/customer-auth/forgot-passwordCualquieraemail. Envía un enlace de restablecimiento válido durante una hora cuando la cuenta existe, y responde igual en ambos casos
POST/api/customer-auth/reset-passwordCualquieratoken (del enlace) y la nueva password. Un enlace caducado o ya usado responde 400 con TOKEN_EXPIRED
POST/api/customer-auth/verify-emailUn asistente con sesión iniciadacode, los seis dígitos del correo, válido durante 24 horas. Los pedidos comprados con esa dirección como invitado se unen a la cuenta
POST/api/customer-auth/resend-verificationUn asistente con sesión iniciadaEnvía un código nuevo; como máximo una vez por minuto (429 con COOLDOWN y retry_after)
GET/api/meUn asistente con sesión iniciadaEl perfil del asistente
PATCH/api/meUn asistente con sesión iniciadaCambia first_name, last_name, email, marketing_emails o reminder_emails
GET/api/me/savedUn asistente con sesión iniciadaEventos guardados, como tarjetas
GET/api/me/saved/slugsUn asistente con sesión iniciadaSolo los slugs de los eventos guardados, para los botones de corazón
PUT/api/me/saved/:slugUn asistente con sesión iniciadaGuardar un evento
DELETE/api/me/saved/:slugUn asistente con sesión iniciadaQuitar un evento de guardados
GET/api/me/ticketsUn asistente con sesión iniciadaLas entradas del asistente como upcoming y past, una tarjeta por pedido
GET/api/me/tickets/:referenceUn asistente con sesión iniciadaLos pases de un pedido, con los códigos QR y los enlaces de descarga
GET/api/me/ordersUn asistente con sesión iniciadaLos pedidos del asistente
GET/api/me/orders/:referenceUn asistente con sesión iniciadaEl recibo de un pedido, con su línea de tiempo

El registro está limitado a 10 por dirección en 10 minutos, y las solicitudes de restablecimiento de contraseña a 5. Mientras no haya una clave de correo, los códigos y los enlaces se escriben en el registro de la API, y mail_simulated lo indica.

Reservas y pago

Una compra son dos llamadas: reservar los asientos o plazas, y luego pagar desde la reserva. Ambas funcionan para un invitado y para un asistente con sesión iniciada, cuyo token se lee cuando se envía.

MétodoRutaQuién puede llamarlaQué hace
POST/api/holdsCualquieraReserva { session_code, seats: ["A12", "B12"] } para asientos reservados, o { session_code, ticket_type_id, quantity } para entrada general, de 1 a 8 a la vez. Necesita Idempotency-Key. Responde 201 con la reserva, su expires_at y el reloj del servidor, y su token, que se muestra una sola vez
GET/api/holds/:idEl propietario de la reserva, con X-Hold-TokenLee la reserva
PATCH/api/holds/:idEl propietario de la reserva, con X-Hold-TokenSustituye la selección; el plazo no se mueve
DELETE/api/holds/:idEl propietario de la reserva, con X-Hold-TokenLibera los asientos ahora
GET/api/checkout/methodsCualquieraLos métodos de pago ofrecidos, cada uno con provider y live
POST/api/checkoutEl propietario de la reserva, con X-Hold-Tokenhold_id, attendee (first_name, last_name, email), provider (stripe, paypal o simulated) y terms_accepted. Necesita Idempotency-Key. Responde 201 con order_reference, status, redirect_url y access_token, el secreto del pedido, que se muestra una sola vez. El Accept-Language de la petición (ar, si no en) se guarda en el pedido como locale, el idioma de cada correo sobre él
  • Una reserva dura el tiempo de reserva del espacio de trabajo (hold_seconds, diez minutos en los datos de ejemplo), contado con el reloj del servidor. Pasado ese tiempo, la reserva responde 410 con HOLD_EXPIRED y los asientos vuelven a estar libres.
  • Un asiento que otra persona tiene reservado o compró responde 409 con SEAT_UNAVAILABLE y los asientos en details.seats; un tipo de entrada completo responde SOLD_OUT; más del límite por pedido responde TOO_MANY.
  • Envía el navegador a redirect_url: la página propia de Stripe o PayPal, o la página del simulador del sitio web. Los datos de la tarjeta nunca se envían a esta API.
  • Una reserva cuyo total es 0 no necesita provider: el pedido se confirma al instante con el proveedor free y el estado paid, y redirect_url es su página de confirmación.

Pedidos, archivos de entradas y pagos

MétodoRutaQuién puede llamarlaQué hace
GET/api/orders/:reference/statusEl asistente del pedido, o un invitado con X-Order-Tokenstatus (pending_payment, paid, payment_failed, expired, payment_review, partially_refunded, refunded), el proveedor y el reloj del servidor, para la página que espera el pago
GET/api/orders/:reference/receiptEl asistente del pedido, o un invitado con X-Order-TokenEl pedido con su evento, recinto, entradas (cada entrada pagada con su código QR), el estado del correo de entradas y los enlaces firmados de downloads
POST/api/orders/:reference/resend-emailEl asistente del pedido, o un invitado con X-Order-TokenVuelve a enviar las entradas a la dirección del pedido, en el idioma del Accept-Language de la petición. Responde 202, o 429 con COOLDOWN dentro del minuto siguiente al último envío
GET/api/orders/:reference/tickets.pdfCualquiera que tenga el enlace firmadoTodas las entradas del pedido en un solo PDF
GET/api/orders/:reference/calendar.icsCualquiera que tenga el enlace firmadoEl evento como archivo de calendario
GET/api/tickets/:reference/pdfCualquiera que tenga el enlace firmadoUna entrada como PDF
GET/api/payments/return/paypalCualquieraPayPal envía aquí al comprador: la API captura el pago y redirige a la página de espera del sitio web (o a su página de cancelado)
POST/api/payments/simulated/:reference/completeLa página del simulador, con el token del pedidotoken y outcome (pay, fail o cancel). Responde 404 siempre que el simulador no se ofrece
POST/api/webhooks/:providerStripe o PayPalstripe o paypal. La firma se comprueba contra STRIPE_WEBHOOK_SECRET o PAYPAL_WEBHOOK_ID; una ausente o incorrecta responde 401. Cada evento se atiende una sola vez, por muchas veces que se envíe
  • Los enlaces de descarga están firmados con exp y sig y funcionan 30 minutos desde el recibo que los creó; uno caducado responde 404, y volver a leer el recibo crea otros nuevos. Se construyen a partir de PUBLIC_API_URL.
  • Las entradas se emiten cuando el proveedor confirma el pago, mediante su webhook, el retorno de PayPal o el simulador. Stripe envía checkout.session.completed, checkout.session.async_payment_succeeded, checkout.session.async_payment_failed y refund.updated; PayPal PAYMENT.CAPTURE.COMPLETED, PAYMENT.CAPTURE.DENIED y PAYMENT.CAPTURE.REFUNDED.
  • El simulador se ofrece mientras no haya definida una clave real de Stripe o PayPal; PAYMENTS_SIMULATOR=on u off lo anula.

El formulario de contacto

MétodoRutaQuién puede llamarlaQué hace
POST/api/leadsCualquieraname, email, subject (general, tickets, organisers, scale, press), message (de 10 a 2000 caracteres) y client_token (un UUID v4). Responde 201 con { id, received_at }
  • Un client_token repetido devuelve el recibo del primer envío en lugar de guardar un segundo.
  • Un campo company rellenado se trata como un bot: la respuesta es igual y no se guarda nada.
  • Cada dirección puede enviar cinco en diez minutos; el siguiente responde 429.

Eventos

MétodoRutaQuién puede llamarlaQué hace
GET/api/admin/eventsPersonal con events.viewEventos con counts por pestaña. tab (all, published, draft, ended), q, category, status, venue (id), from, to, sort (starts_at, si no la última actualización), order (asc, desc), page, limit
GET/api/admin/events/:idPersonal con events.viewUn evento para el editor, con su lista de comprobación readiness, version y el inicio y el fin en hora local
POST/api/admin/eventsPersonal con events.editCrea un borrador: title, summary, description (cada uno en, ar), category (slug), venue_id, color (pink, yellow, teal, blue), admission_mode (reserved, general), visibility (public, unlisted), starts_local, ends_local, time_zone, agenda y ticket_types (title, price_minor, capacity, y opcionalmente description, max_per_order, status), opcionalmente slug
PATCH/api/admin/events/:idPersonal con events.editGuarda los mismos campos con la version que cargó el editor. Un guardado más reciente responde 409 con VERSION_CONFLICT; el precio de un tipo de entrada vendido está bloqueado (PRICE_LOCKED)
POST/api/admin/events/:id/publishPersonal con events.publishPone un borrador a la venta. Uno que no está listo responde 400 con NOT_READY y lo que falta
POST/api/admin/events/:id/unpublishPersonal con events.publishVuelve a borrador: las ventas se detienen y las reservas se liberan, las entradas ya vendidas siguen siendo válidas
POST/api/admin/events/:id/cancelPersonal con events.publish{ confirm }, el slug del evento escrito completo. Las ventas y la admisión se detienen, y se envía un correo al titular de cada pedido pagado. Los reembolsos se hacen después, pedido por pedido
POST/api/admin/events/:id/duplicatePersonal con events.editUn borrador nuevo con los mismos detalles y tipos de entrada, y sin ventas
POST/api/admin/events/:id/archivePersonal con events.publishArchiva un borrador, o un evento que ha terminado o se ha cancelado
GET/api/admin/events/:id/attendeesPersonal con events.viewLas entradas del evento con titular, asiento, tipo, estado y hora de admisión. q, status (admitted, not_admitted, void), page, limit

Recintos y planos de asientos

MétodoRutaQuién puede llamarlaQué hace
GET/api/admin/venuesPersonal con venues.viewRecintos. q, city, page, limit
GET/api/admin/venues/mapPersonal con venues.viewEl marcador de cada recinto para el mapa
GET/api/admin/venues/:idPersonal con venues.viewUn recinto con sus planos
POST/api/admin/venuesPersonal con venues.editAñade un recinto: name (en, ar), address, city, time_zone, capacity, accessibility (en, ar), y opcionalmente slug, transit, location (latitude, longitude)
PATCH/api/admin/venues/:idPersonal con venues.editCambia cualquiera de esos campos
GET/api/admin/venues/:id/layoutsPersonal con venues.viewLas versiones del plano del recinto
GET/api/admin/venues/:id/layouts/:versionPersonal con venues.viewUna versión con sus asientos
POST/api/admin/venues/:id/layoutsPersonal con venues.editEmpieza un borrador nuevo
PATCH/api/admin/venues/:id/layouts/:versionPersonal con venues.editGuarda el borrador: rows (de 1 a 40), seats_per_row (de 1 a 60), aisles_after (hasta 6), seats (label, y opcionalmente accessible, companion, disabled, price_tier de 0 a 9) y loaded_at. Un borrador guardado por otra persona desde entonces responde 409 con VERSION_CONFLICT
POST/api/admin/venues/:id/layouts/:version/publishPersonal con venues.edit{ acknowledged: true }. Publica el borrador como el plano del recinto; los asientos ya vendidos conservan la versión con la que se vendieron. Se rechaza un plano vacío, o con más asientos que el aforo del recinto (OVER_CAPACITY)

Pedidos, entradas y reembolsos

MétodoRutaQuién puede llamarlaQué hace
GET/api/admin/ordersPersonal con orders.viewPedidos con counts por estado. status (paid, pending_payment, refunded, payment_failed, payment_review), event (slug), provider (stripe, paypal, simulated, free), q (referencia, correo o nombre), from, to, page, limit
GET/api/admin/orders/eventsPersonal con orders.viewCada evento que tiene pedidos, para el filtro de la página de pedidos
GET/api/admin/orders/:referencePersonal con orders.viewUn pedido: entradas, reembolsos, la línea de tiempo del pago, un enlace a él en el panel del proveedor y su version
GET/api/admin/orders/:reference/refund-previewPersonal con refunds.createLo que devolvería reembolsar ?tickets=TKT-1042-2,…, por entrada
POST/api/admin/orders/:reference/refundsPersonal con refunds.createReembolsa entradas completas: tickets (de 1 a 8 referencias), reason (customer_request, event_cancelled, duplicate_order, event_changed, other), acknowledged (true) y order_version. Necesita Idempotency-Key. Responde 202 con el reembolso pending
POST/api/admin/refunds/:id/retryPersonal con refunds.createVuelve a enviar al proveedor un reembolso fallido
POST/api/admin/refunds/:id/restorePersonal con refunds.createCierra definitivamente un reembolso fallido; sus entradas vuelven a ser válidas
POST/api/admin/tickets/:reference/reissuePersonal con tickets.manageUn código QR nuevo para una entrada válida; el código antiguo deja de funcionar en la puerta
POST/api/admin/tickets/:reference/voidPersonal con tickets.manageAnula una entrada gratuita. Una entrada pagada responde 409 con USE_REFUND: se reembolsa en su lugar

Sus entradas se suspenden (refund_pending) en cuanto se pide el reembolso, así que la puerta las rechaza. El reembolso se resuelve cuando el proveedor lo confirma, unos segundos después en el simulador: las entradas se anulan entonces y sus asientos vuelven a la venta. Un reembolso fallido las mantiene suspendidas hasta que se reintenta o se restaura, lo que las vuelve a hacer válidas. Lee el pedido de nuevo para ver en qué punto está.

Control de acceso en la puerta

MétodoRutaQuién puede llamarlaQué hace
GET/api/admin/check-in/sessionsPersonal con checkin.scanLas sesiones que este miembro puede escanear, desde hace un día en adelante, con los recuentos de admitidos y esperados y si las puertas están abiertas
GET/api/admin/check-in/sessions/:code/summaryPersonal con checkin.scanAdmitidos, esperados, restantes y las alertas pendientes
GET/api/admin/check-in/sessions/:code/scansPersonal con checkin.scanLos escaneos recientes, cada uno admitted, eligible, duplicate, wrong_session, void o not_found
POST/api/admin/check-in/sessions/:code/acknowledgePersonal con checkin.scanMarca las alertas de la sesión como vistas
POST/api/admin/check-in/validatePersonal con checkin.scansession_code y code: lo que leyó la cámara, o una referencia de entrada escrita como TKT-1042-1. Dice si la entrada puede entrar, sin admitirla
POST/api/admin/check-in/admitPersonal con checkin.scanLo mismo con client_request_id (un UUID), y admite la entrada. Una entrada que ya entró responde 409 con ALREADY_ADMITTED, cuándo y quién; WRONG_SESSION y TICKET_VOID también se rechazan
GET/api/admin/session-staffPersonal con admins.editQué personal de control de acceso está asignado a qué sesiones
PUT/api/admin/session-staff/:codePersonal con admins.editDefine el personal de puerta de una sesión: admin_ids, separados por comas

Los miembros que pueden editar o publicar eventos llegan a todas las sesiones; los demás solo a las sesiones que tienen asignadas, y otra responde 403. Cada miembro puede hacer 120 comprobaciones por minuto.

Resumen, informes y exportaciones

MétodoRutaQuién puede llamarlaQué hace
GET/api/admin/overviewPersonal con overview.viewEl resumen: totales, la serie de ventas, ventas por evento, proveedor y categoría, la puerta en vivo, los próximos eventos y lo que necesita atención. range (last_7_days, last_30_days, this_month, all), last_30_days por defecto
GET/api/admin/reportsPersonal con reports.viewLas mismas cifras de ventas, para range, o from y to, y opcionalmente un event
POST/api/admin/reports/exportPersonal con reports.exportInicia un CSV: kind (orders, sales, attendees) y filters opcional. Responde 202 con su id
GET/api/admin/reports/exports/:idPersonal con reports.exportCómo va la exportación; cuando está lista, su download_url
GET/api/admin/reports/exports/:id/downloadCualquiera que tenga el token del enlaceEl archivo CSV. El enlace funciona durante una hora y se muestra una sola vez

Los archivos CSV se escriben en EXPORT_DIR en segundo plano, y el enlace de descarga se construye a partir de PUBLIC_API_URL.

Espacio de trabajo, pagos y ajustes del sitio

MétodoRutaQuién puede llamarlaQué hace
GET/api/admin/workspacePersonal con settings.viewEl espacio de trabajo: nombre, correo de soporte, moneda, zona horaria, comisión de reserva (fee_bps), hold_seconds y max_per_order (solo lectura: son columnas cargadas desde back-end/src/database/seeders/data/settings.json), y notification_settings, los interruptores de la campana de notificaciones del equipo
PATCH/api/admin/workspacePersonal con settings.editCambia name, support_email, currency (USD, EUR, GBP, AED, SAR), time_zone, fee_bps (de 0 a 2000, centésimas de porcentaje; el asistente siempre lo paga al pagar) o notification_settings (order_paid, refund_requested, checkin_alerts), con la version cargada. La moneda se bloquea cuando el espacio de trabajo ha vendido (CURRENCY_LOCKED). Cualquier otro campo, incluidos fee_payer, hold_seconds y max_per_order, responde 400
GET/api/admin/payment-providersPersonal con settings.viewEl configured, live y offered de cada proveedor. Las claves permanecen en el .env de la API y nunca se devuelven
GET/api/settingsPersonal con settings.viewTodos los ajustes del sitio. search, category, page, page_count
GET/api/settings/:keyPersonal con settings.viewUn ajuste por clave
PATCH/api/settings/:keyPersonal con settings.editCambiar el valor de un ajuste
DELETE/api/settings/:keyPersonal con settings.editEliminar un ajuste

Equipo y roles

MétodoRutaQuién puede llamarlaQué hace
GET/api/adminsPersonal con admins.viewEl equipo del espacio de trabajo. email, name, phone (deben coincidir todos los dados), page, page_count
GET/api/admins/statisticsPersonal con admins.viewRecuentos para la lista del equipo
GET/api/admins/:idPersonal con admins.viewUn miembro, por id o nombre de usuario
POST/api/adminsPersonal con admins.createAñade un miembro: first_name, last_name, email, password y password_confirmation (6 caracteres o más), opcionalmente phone
PATCH/api/admins/:idPersonal con admins.editCambia un miembro
PATCH/api/admins/:id/rolesPersonal con admins.assign_rolesDefine los roles de un miembro: role_ids
DELETE/api/admins/:idPersonal con admins.deleteSaca a un miembro del espacio de trabajo actual. La cuenta en sí se borra solo cuando era su último espacio de trabajo; data.removed responde workspace o account. Eliminarse a uno mismo responde 403 con REMOVE_SELF, y eliminar al último propietario del espacio de trabajo 409 con LAST_OWNER
PATCH/api/admins/profileCualquier miembro del personal con sesión iniciadaCambia los propios first_name, last_name, email, phone, profile_picture o country_id del miembro con sesión iniciada. Un password o role_ids en el cuerpo responde 400: la contraseña tiene su propia ruta
PATCH/api/admins/profile/passwordCualquier miembro del personal con sesión iniciadaCambia la propia contraseña del miembro con sesión iniciada: current_password, password, password_confirmation
GET/api/rolesPersonal con roles.viewRoles. name, guard_name, created_from, created_to, page, page_count
GET/api/roles/statisticsPersonal con roles.viewRecuentos para la lista de roles
GET/api/roles/selectPersonal con roles.viewEl id y el nombre de cada rol, para un selector
GET/api/roles/permissionsPersonal con roles.viewTodos los permisos, agrupados por área
GET/api/roles/:idPersonal con roles.viewUn rol con sus permisos
POST/api/rolesPersonal con roles.createAñade un rol: name
PUT/api/roles/:idPersonal con roles.editRenombra un rol: name
POST/api/roles/:id/permissionsPersonal con roles.assign_permissionsDefine los permissions de un rol, por nombre
DELETE/api/roles/:idPersonal con roles.deleteElimina un rol

Consultas, notificaciones y subidas

MétodoRutaQuién puede llamarlaQué hace
GET/api/leadsPersonal con leads.viewConsultas del formulario de contacto, con recuentos por estado. status, q, received_within_days, page, page_size
GET/api/leads/:idPersonal con leads.viewUna consulta
PATCH/api/leads/:idPersonal con leads.editDefine status (new, contacted, closed), notes o assigned_admin_id
GET/api/notificationsCualquier miembro del personal con sesión iniciadaLas 30 notificaciones más recientes del miembro con sesión iniciada
PATCH/api/notifications/read-allCualquier miembro del personal con sesión iniciadaMarcarlas todas como leídas
PATCH/api/notifications/:id/readCualquier miembro del personal con sesión iniciadaMarca una como leída
DELETE/api/notifications/:idCualquier miembro del personal con sesión iniciadaElimina una
POST/api/helpers/uploadCualquier miembro del personal con sesión iniciadaGuarda un archivo (multipart file, con path para la carpeta, for para el ajuste de tamaño como venue, cover, logo o profile, y type). Las fotos se recodifican, con un máximo de 1920 píxeles de ancho; los vídeos se aceptan como MP4, WebM, MOV o M4V; 150 MB como máximo. Responde con las direcciones del archivo guardado

Las notificaciones cubren pedidos pagados, solicitudes de reembolso, alertas de la puerta, consultas nuevas y conceptos de recinto terminados, y se conservan 30 días. Una subida no tiene permiso propio: lo que el archivo llega a ser lo comprueba la ruta que lo guarda. Los archivos van al bucket R2 cuando sus cinco variables están definidas, y a MEDIA_UPLOAD_DIR en caso contrario.

Límites por dirección

RutaLímiteVariable
POST /api/auth/login, POST /api/customer-auth/login10 inicios de sesión fallidos cada 15 minutos, cada uno contado por separadoRATE_LIMIT_LOGIN
POST /api/customer-auth/register10 cada 10 minutosNinguno
POST /api/customer-auth/forgot-password5 cada 10 minutosNinguno
POST /api/leads5 cada 10 minutosNinguno
POST /api/admin/check-in/validate, /admit120 por minuto por miembro del personalNinguno
POST /api/customer-auth/resend-verification, POST /api/orders/:reference/resend-emailUna vez por minutoNinguno

Una petición que supera un límite responde 429. Las cuentas están en la memoria de la API, así que un reinicio las borra. Detrás de un proxy inverso, define TRUST_PROXY para que cada visitante se cuente en su propia dirección.

Asistente de eventos con IA y sus conversaciones

Incluido con tu compra. Inicia sesión para leerlo o ábrelo en tu descarga.

La ruta de streaming del asistente, su lista de modelos, la aprobación de borradores y las conversaciones guardadas.

Estudio de recintos

Incluido con tu compra. Inicia sesión para leerlo o ábrelo en tu descarga.

Las rutas del estudio: generaciones y los conceptos guardados en un recinto.

Servidor MCP

Incluido con tu compra. Inicia sesión para leerlo o ábrelo en tu descarga.

El endpoint MCP para agentes de programación y cómo se autoriza.

Actualizaciones en directo por WebSocket

Incluido con tu compra. Inicia sesión para leerlo o ábrelo en tu descarga.

Los namespaces de Socket.IO que escucha el panel, sus eventos y cómo se autoriza una conexión.

Rutas del modo demostración

Incluido con tu compra. Inicia sesión para leerlo o ábrelo en tu descarga.

Las rutas que existen solo para una compilación de demostración pública.

¿Te atascaste en un paso?

Busca una solución antes de empezar de nuevo.

Solución de problemas

Preferencias de Cookies

Utilizamos cookies para mejorar tu experiencia de navegación, analizar el tráfico del sitio y personalizar el contenido. Al hacer clic en "Aceptar Todo", consientes nuestro uso de cookies para análisis y publicidad personalizada.