{"openapi":"3.0.3","info":{"title":"Congreso Peruano de Geología 2026 - API de Pases y Credenciales","version":"1.0.0","description":"\nAPI REST oficial para la gestión, emisión, consulta y control de accesos del **XXII Congreso Peruano de Geología 2026** (Sociedad Geológica del Perú).\n\n### 🔑 Autenticación\nTodas las rutas de la API v1 requieren una clave de API (**API Key**) enviada mediante Headers HTTP:\n* **Header Personalizado:** `x-api-key: cpg_live_...`\n* **Bearer Token:** `Authorization: Bearer cpg_live_...`\n\nPuedes generar y administrar tus claves en el panel [**/admin/api-keys**](https://registro.corptecperu.com/admin/api-keys).\n\n### 💡 Formatos de Envío\nPuedes enviar tus solicitudes usando:\n1. **Campos Individuales Formulario:** (`application/x-www-form-urlencoded` o `multipart/form-data`) para rellenar campo por campo en Swagger UI.\n2. **Cuerpo JSON:** (`application/json`) para enviar objetos o listas masivas (batch).\n      ","contact":{"name":"Sociedad Geológica del Perú (CPG 2026)","url":"https://congresosgp.org.pe"}},"servers":[{"url":"https://registro.corptecperu.com","description":"Servidor Actual"}],"components":{"securitySchemes":{"ApiKeyHeader":{"type":"apiKey","in":"header","name":"x-api-key","description":"Clave de API enviada en el header x-api-key"},"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API Key (cpg_live_...)","description":"Clave de API enviada en el header Authorization: Bearer <key>"}},"schemas":{"CreateUserPayload":{"type":"object","required":["email","password"],"properties":{"email":{"type":"string","format":"email","description":"Correo electrónico único de acceso para el usuario / stand / empresa","example":"stand.oxiservi@cpg2026.pe"},"password":{"type":"string","minLength":6,"description":"Contraseña de acceso inicial (mínimo 6 caracteres)","example":"Oxiservi2026!"},"name":{"type":"string","description":"Nombre del stand, empresa o contacto responsable","example":"Stand OXISERVI SRL"},"company_name":{"type":"string","description":"Razón Social o Nombre de la Empresa Expositora","example":"OXISERVI SRL"},"role":{"type":"string","enum":["stand","empresa","scanner","admin","attendee"],"default":"stand","description":"Rol en el sistema: \"stand\" (Expositor), \"empresa\" (Delegación Corporativa), \"scanner\" (Control de Puerta), \"admin\" (Organizador)","example":"stand"},"allocated_tickets":{"type":"integer","default":50,"description":"Cuota de pases / credenciales asignadas a este stand o empresa (ej. 50 para stands, 5 para empresas)","example":50}}},"UpdateUserPayload":{"type":"object","properties":{"company_name":{"type":"string","description":"Nombre de la empresa o stand","example":"OXISERVI SRL"},"name":{"type":"string","description":"Nombre de la persona de contacto","example":"Juan Pérez"},"role":{"type":"string","enum":["stand","empresa","scanner","admin","attendee"],"description":"Rol de la cuenta"},"add_tickets":{"type":"integer","description":"Cantidad de entradas a SUMAR a la cuota actual (ej. +10)","example":10},"allocated_tickets":{"type":"integer","description":"Fijar cuota exacta de entradas (reemplaza el valor actual)","example":60},"password":{"type":"string","minLength":6,"description":"Nueva contraseña para restablecer la cuenta","example":"NuevaPassword2026!"}}},"UserTicketsActionPayload":{"type":"object","properties":{"add_tickets":{"type":"integer","description":"Sumar entradas a la cuota del usuario (ej. 15)","example":15},"set_quota":{"type":"integer","description":"Establecer cuota total exacta (ej. 100)","example":100},"generate_links":{"type":"boolean","description":"Si es true, pre-genera credenciales pendientes con enlace único y mensaje listo de WhatsApp","example":true},"count":{"type":"integer","description":"Número de enlaces de invitación a generar (usado si generate_links es true)","example":5}}},"CreateTicketPayload":{"type":"object","required":["dni"],"properties":{"first_name":{"type":"string","description":"Nombres del asistente","example":"CARLOS ISAAC"},"last_name":{"type":"string","description":"Apellidos del asistente","example":"BIANCHI RAMIREZ"},"maternal_last_name":{"type":"string","description":"Apellido materno (opcional)","example":"RAMIREZ"},"dni":{"type":"string","description":"Número de DNI o documento de identidad oficial","example":"09305450"},"email":{"type":"string","format":"email","description":"Correo electrónico del asistente","example":"c.bianchiramirez@gmail.com"},"phone":{"type":"string","description":"Teléfono o celular de contacto","example":"989176711"},"city":{"type":"string","description":"Ciudad de procedencia","example":"LIMA"},"address":{"type":"string","description":"Dirección física","example":"AV. SAN JOSÉ 368 BELLAVISTA - CALLAO"},"institution":{"type":"string","description":"Empresa o Institución a la que representa","example":"OIL & GAS SENIOR CONSULTANT"},"job_title":{"type":"string","description":"Cargo u ocupación","example":"INDEPENDIENTE"},"cip_number":{"type":"string","description":"Número de Colegiatura CIP (si aplica)","example":"182930"},"detail_category":{"type":"string","description":"Categoría del participante en el congreso","example":"PARTICIPANTE SOCIO SGP HABILITADO"},"badge_name":{"type":"string","description":"Texto para el fotocheck (Línea Principal)","example":"CARLOS BIANCHI"},"badge_subtitle":{"type":"string","description":"Texto para el fotocheck (Subtítulo)","example":"PRESIDENTE DE SGP"},"receipt_number":{"type":"string","description":"Número de comprobante (Boleta o Factura)","example":"BOL EB01-4756"},"invoice_date":{"type":"string","description":"Fecha de emisión del comprobante","example":"1/04/2026"},"bank":{"type":"string","description":"Banco de abono o método de pago","example":"BCP"},"payment_status":{"type":"string","description":"Estado de pago: \"FACTURADO Y PAGADO\" o \"FALTA PAGO POR PARTE DE LA EMPRESA\"","example":"FACTURADO Y PAGADO"},"pending_balance":{"type":"number","description":"Saldo pendiente por cobrar en dólares o soles (0 si está pagado)","example":0}}},"UpdateTicketPayload":{"type":"object","properties":{"payment_status":{"type":"string","description":"Estado de pago: \"PAGADO\" o \"FALTA PAGO POR PARTE DE LA EMPRESA\"","example":"FACTURADO Y PAGADO"},"pending_balance":{"type":"number","description":"Saldo pendiente de cobro","example":0},"institution":{"type":"string","description":"Empresa o institución","example":"MINERA CHINALCO S.A."},"phone":{"type":"string","description":"Teléfono de contacto","example":"987123456"},"badge_name":{"type":"string","description":"Nombre impreso en fotocheck"},"badge_subtitle":{"type":"string","description":"Subtítulo impreso en fotocheck"}}},"Ticket":{"type":"object","properties":{"id":{"type":"string","format":"uuid","example":"11111111-1111-1111-1111-111111111111"},"first_name":{"type":"string","example":"CARLOS ISAAC"},"last_name":{"type":"string","example":"BIANCHI"},"maternal_last_name":{"type":"string","example":"RAMIREZ"},"dni":{"type":"string","example":"09305450"},"ruc":{"type":"string","example":"20100128456"},"phone":{"type":"string","example":"989176711"},"city":{"type":"string","example":"LIMA"},"institution":{"type":"string","example":"OIL & GAS SENIOR CONSULTANT"},"job_title":{"type":"string","example":"INDEPENDIENTE"},"cip_number":{"type":"string","example":"182930"},"detail_category":{"type":"string","example":"PARTICIPANTE SOCIO SGP HABILITADO"},"badge_name":{"type":"string","example":"CARLOS BIANCHI"},"badge_subtitle":{"type":"string","example":"PRESIDENTE DE SGP"},"receipt_number":{"type":"string","example":"BOL EB01-4756"},"invoice_date":{"type":"string","example":"1/04/2026"},"payment_status":{"type":"string","example":"FACTURADO Y PAGADO"},"pending_balance":{"type":"number","example":0},"currency":{"type":"string","example":"USD"},"bank":{"type":"string","example":"BCP"},"status":{"type":"string","enum":["active","pending","used"],"example":"active"},"used":{"type":"boolean","example":false},"qr_code":{"type":"string"},"direct_url":{"type":"string","example":"https://registro.corptecperu.com/tickets/11111111-1111-1111-1111-111111111111"},"metadata":{"type":"object","properties":{"check_ins":{"type":"array","items":{"type":"object","properties":{"day":{"type":"integer","example":1},"date":{"type":"string","example":"2026-09-21"},"entered_at":{"type":"string","format":"date-time"}}}}}},"created_at":{"type":"string","format":"date-time"}}},"UserAccount":{"type":"object","properties":{"id":{"type":"string","format":"uuid","example":"5382d3f3-05df-4d4c-acc4-a7a4c1835af8"},"email":{"type":"string","format":"email","example":"stand.oxiservi@cpg2026.pe"},"name":{"type":"string","example":"Stand OXISERVI SRL"},"company_name":{"type":"string","example":"OXISERVI SRL"},"role":{"type":"string","enum":["stand","empresa","scanner","admin","attendee"],"example":"stand"},"allocated_tickets":{"type":"integer","example":50},"completed_tickets":{"type":"integer","example":15},"pending_tickets":{"type":"integer","example":5},"remaining_quota":{"type":"integer","example":30},"created_at":{"type":"string","format":"date-time"}}},"ErrorResponse":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string","example":"Descripción del error"}}}}},"security":[{"ApiKeyHeader":[]},{"BearerAuth":[]}],"paths":{"/api/v1/users":{"get":{"tags":["Usuarios & Stands"],"summary":"Listar usuarios, stands y empresas con métricas de cuota","description":"Devuelve todas las cuentas registradas con desglose de cuotas, pases completados y restantes.","parameters":[{"name":"role","in":"query","schema":{"type":"string","enum":["stand","empresa","scanner","admin","attendee","all"]},"description":"Filtrar por rol"},{"name":"search","in":"query","schema":{"type":"string"},"description":"Búsqueda por nombre, empresa o correo"},{"name":"page","in":"query","schema":{"type":"integer","default":1}},{"name":"limit","in":"query","schema":{"type":"integer","default":50}}],"responses":{"200":{"description":"Lista de usuarios obtenida exitosamente","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"total":{"type":"integer","example":45},"users":{"type":"array","items":{"$ref":"#/components/schemas/UserAccount"}}}}}}}}},"post":{"tags":["Usuarios & Stands"],"summary":"Crear nueva cuenta para Stand o Empresa con Correo y Contraseña","description":"Crea una cuenta en el sistema para dar acceso al portal de stands o empresas con cuota de entradas asignada.","requestBody":{"required":true,"description":"Datos de la cuenta a crear (rellena los campos individuales abajo o cambia el selector a JSON)","content":{"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/CreateUserPayload"}},"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserPayload"},"example":{"email":"stand.oxiservi@cpg2026.pe","password":"Oxiservi2026!","name":"Stand OXISERVI SRL","company_name":"OXISERVI SRL","role":"stand","allocated_tickets":50}}}},"responses":{"201":{"description":"Cuenta de usuario creada exitosamente","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"user":{"$ref":"#/components/schemas/UserAccount"}}}}}},"400":{"description":"Datos inválidos o correo ya registrado"}}}},"/api/v1/users/{id}":{"get":{"tags":["Usuarios & Stands"],"summary":"Consultar cuenta de usuario y tickets asignados","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"UUID o correo electrónico del usuario"}],"responses":{"200":{"description":"Detalle de usuario y lista de sus tickets","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"user":{"$ref":"#/components/schemas/UserAccount"},"tickets":{"type":"array","items":{"$ref":"#/components/schemas/Ticket"}}}}}}},"404":{"description":"Usuario no encontrado"}}},"patch":{"tags":["Usuarios & Stands"],"summary":"Actualizar perfil, cuota o contraseña de usuario","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"UUID o correo electrónico del usuario"}],"requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/UpdateUserPayload"}},"application/json":{"schema":{"$ref":"#/components/schemas/UpdateUserPayload"},"example":{"company_name":"OXISERVI SRL","add_tickets":10,"role":"stand"}}}},"responses":{"200":{"description":"Usuario actualizado exitosamente"},"404":{"description":"Usuario no encontrado"}}},"delete":{"tags":["Usuarios & Stands"],"summary":"Eliminar cuenta de usuario","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Usuario eliminado exitosamente"}}}},"/api/v1/users/{id}/tickets":{"get":{"tags":["Usuarios & Stands"],"summary":"Listar pases creados por un Stand o Empresa","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Lista de tickets del usuario","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"total":{"type":"integer"},"tickets":{"type":"array","items":{"$ref":"#/components/schemas/Ticket"}}}}}}}}},"post":{"tags":["Usuarios & Stands"],"summary":"Asignar más cuota o pre-generar enlaces de WhatsApp","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/UserTicketsActionPayload"}},"application/json":{"schema":{"$ref":"#/components/schemas/UserTicketsActionPayload"},"example":{"add_tickets":10,"generate_links":true,"count":5}}}},"responses":{"200":{"description":"Cuota actualizada y/o pases generados","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"allocated_tickets":{"type":"integer","example":60},"generated_passes":{"type":"array","items":{"type":"object","properties":{"ticket_id":{"type":"string"},"claim_url":{"type":"string"},"whatsapp_url":{"type":"string"}}}}}}}}}}}},"/api/v1/tickets":{"get":{"tags":["Tickets & Credenciales"],"summary":"Listar y filtrar tickets del congreso","parameters":[{"name":"dni","in":"query","schema":{"type":"string"},"description":"Filtrar por número de DNI"},{"name":"ruc","in":"query","schema":{"type":"string"},"description":"Filtrar por RUC de empresa"},{"name":"status","in":"query","schema":{"type":"string","enum":["active","pending","used"]},"description":"Filtrar por estado del pase"},{"name":"payment_status","in":"query","schema":{"type":"string"},"description":"Filtrar por estado de pago (ej. PAGADO o FALTA PAGO)"},{"name":"page","in":"query","schema":{"type":"integer","default":1}},{"name":"limit","in":"query","schema":{"type":"integer","default":50}}],"responses":{"200":{"description":"Lista de tickets obtenida exitosamente","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"total":{"type":"integer","example":120},"page":{"type":"integer","example":1},"limit":{"type":"integer","example":50},"tickets":{"type":"array","items":{"$ref":"#/components/schemas/Ticket"}}}}}}}}},"post":{"tags":["Tickets & Credenciales"],"summary":"Crear ticket(s) individual o en lote (Batch)","requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/CreateTicketPayload"}},"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/CreateTicketPayload"},{"type":"object","properties":{"tickets":{"type":"array","items":{"type":"object"}}}}]},"example":{"first_name":"CARLOS ISAAC","last_name":"BIANCHI RAMIREZ","dni":"09305450","email":"c.bianchi@gmail.com","phone":"989176711","institution":"OIL & GAS SENIOR CONSULTANT","job_title":"PRESIDENTE DE SGP","payment_status":"FACTURADO Y PAGADO","pending_balance":0,"receipt_number":"BOL EB01-4756"}}}},"responses":{"201":{"description":"Ticket creado exitosamente","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"ticket":{"$ref":"#/components/schemas/Ticket"}}}}}},"400":{"description":"Datos requeridos faltantes"}}}},"/api/v1/tickets/{id}":{"get":{"tags":["Tickets & Credenciales"],"summary":"Consultar ticket por ID o DNI","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"UUID del ticket o número de DNI"}],"responses":{"200":{"description":"Ticket encontrado","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/Ticket"}}}}}},"404":{"description":"Ticket no encontrado"}}},"patch":{"tags":["Tickets & Credenciales"],"summary":"Actualizar ticket o estado de pago","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/UpdateTicketPayload"}},"application/json":{"schema":{"$ref":"#/components/schemas/UpdateTicketPayload"},"example":{"payment_status":"FACTURADO Y PAGADO","pending_balance":0,"institution":"MINERA CHINALCO S.A."}}}},"responses":{"200":{"description":"Ticket actualizado correctamente"},"404":{"description":"Ticket no encontrado"}}}},"/api/admin/settings":{"get":{"tags":["Configuración del Congreso"],"summary":"Consultar configuración y fechas del congreso","responses":{"200":{"description":"Fechas y métricas de días del evento","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"settings":{"type":"object","properties":{"event_name":{"type":"string","example":"Congreso Peruano de Geología 2026"},"start_date":{"type":"string","example":"2026-09-21"},"end_date":{"type":"string","example":"2026-09-23"},"total_days":{"type":"integer","example":3}}}}}}}}}}}}}