CelebraeCelebrae
Celebrae

Descubre experiencias únicas para grupos. Vive momentos inolvidables con tus amigos.

Explorar

  • Experiencias
  • Locales
  • Categorías
  • Blog

Para negocios

  • Vende más con Celebrae
  • Guía para negocios
  • Cómo vender más experiencias
  • API / Desarrolladores

Soporte

  • Qué es Celebrae
  • Centro de Ayuda
  • Sobre Nosotros
  • Contacto

Legal

  • Términos y Condiciones
  • Política de Privacidad
  • Política de Cookies
  • Eliminación de datos
  • Arrepentimiento / revocación

© 2026 Celebrae. Todos los derechos reservados.

Al usar esta plataforma, aceptas nuestros Términos y Condiciones y Política de Privacidad.

CelebraeCelebrae
CELEBRAE
¿Eres nuevo?Regístrate
Cargando...
ExperienciasLocalesMapaCómo FuncionaTiendaAPIVende más con Celebrae
Portal desarrolladores
Referencia APIGuía desarrolladorPostman

API Reference - Celebrae v1

Documentación técnica de la API pública de Celebrae para integraciones server-to-server.

Base URL: https://www.celebrae.com/api/v1

Colección Postman: Descarga celebrae-api-postman.json e impórtala en Postman. Configura las variables base_url (debe incluir /api/v1), client_id y secret en la colección.


Índice

  1. Autenticación
  2. Errores
  3. Shops
  4. Experiencias
  5. Extras
  6. Bookings
  7. Webhooks
  8. Webhooks salientes (consumir)

Autenticación

Todas las peticiones a /api/v1/* requieren autenticación server-to-server.

Formato

Authorization: Bearer <client_id>:<secret>
  • client_id: Identificador del API client (ej. ce_a1b2c3d4...)
  • secret: Secreto compartido (solo se muestra una vez al crear el client)

Ejemplo

curl -H "Authorization: Bearer ce_abc123:tu_secreto_aqui" \
  https://api.celebrae.com/api/v1/shops

Obtención de credenciales

Si tienes un local en Celebrae, crea tus credenciales desde el panel de seller: Mi local → API y webhooks → Credenciales. El client_id y el secret se muestran una sola vez al crear.

# Crear client de prueba (solo desarrollo/admin)
npx tsx scripts/seed-api-client.ts <shop_id>

Scopes

Cada API client tiene scopes que definen qué puede hacer:

ScopePermisos
shops:readListar y ver detalle de shops
shops:write(Reservado)
experiences:readListar y ver experiencias y extras
experiences:write(Reservado)
bookings:readVer reservas
bookings:writeCrear reservas
webhooks:readVer estado de deliveries y listar endpoints
webhooks:writeCrear, actualizar y eliminar endpoints de webhook

Multi-tenant

Un API client puede tener acceso a varios shops (negocios). La asociación se gestiona en api_client_shops.


Errores

La API usa RFC 7807 Problem Details.

Formato

{
  "type": "https://api.celebrae.com/errors/404",
  "title": "Not Found",
  "status": 404,
  "detail": "Resource not found",
  "instance": "/api/v1/shops/xxx",
  "code": "NOT_FOUND"
}

Códigos HTTP

StatusSignificado
200OK
201Created
400Bad Request - Validación fallida
401Unauthorized - Credenciales inválidas o faltantes
403Forbidden - Sin permiso (scope o tenant)
404Not Found - Recurso no existe o no tienes acceso
409Conflict - Idempotency key ya usada con otro body
429Too Many Requests - Rate limit excedido
500Internal Server Error

Rate limit y headers

Planes homologados: free (no consume por API), nitro, pro, enterprise. El plan del API client determina los límites.

  • X-RateLimit-Limit: Límite por minuto (ej. 100 para pro).
  • X-RateLimit-Remaining: Peticiones restantes en la ventana actual.
  • X-RateLimit-Reset: Timestamp Unix (segundos) de cuándo se resetea el contador.
  • x-request-id: ID de correlación (incluye en soporte si reportas un error).

Códigos de error comunes

codeDescripción
INSUFFICIENT_SCOPEFalta el scope requerido
IDEMPOTENCY_KEY_REQUIREDPOST /bookings requiere header Idempotency-Key
IDEMPOTENCY_CONFLICTMisma key con body distinto
VALIDATION_ERRORBody inválido
NOT_FOUNDRecurso no encontrado

Shops

GET /shops

Lista los shops a los que tiene acceso el API client.

Scope: shops:read

Query params:

ParamTipoDefaultDescripción
limitnumber20Máx 100
offsetnumber0Paginación

Respuesta 200:

{
  "shops": [
    {
      "id": "uuid",
      "name": "Mi Local",
      "slug": "mi-local",
      "short_description": "...",
      "address": "...",
      "country": "ES",
      "currency": "EUR",
      "email": "contacto@local.com",
      "phone": "+34...",
      "website": "https://...",
      "created_at": "2024-01-15T10:00:00Z"
    }
  ],
  "total": 1
}

GET /shops/:id

Detalle de un shop.

Scope: shops:read

Respuesta 200:

{
  "id": "uuid",
  "name": "Mi Local",
  "slug": "mi-local",
  "description": "...",
  "short_description": "...",
  "address": "...",
  "address_line_2": "...",
  "country": "ES",
  "currency": "EUR",
  "email": "...",
  "phone": "...",
  "website": "...",
  "created_at": "2024-01-15T10:00:00Z"
}

Experiencias

GET /shops/:id/experiences

Lista experiencias (kits) del shop.

Scope: experiences:read

Query params:

ParamTipoDefaultDescripción
limitnumber20Máx 100
offsetnumber0Paginación
statusstring-active, paused, draft, archived

Respuesta 200:

{
  "experiences": [
    {
      "id": "uuid",
      "title": "Tour guiado",
      "slug": "tour-guiado",
      "short_description": "...",
      "base_price": 25.00,
      "currency": "EUR",
      "duration_minutes": 120,
      "status": "active",
      "created_at": "2024-01-15T10:00:00Z"
    }
  ]
}

GET /experiences/:id

Detalle de una experiencia.

Scope: experiences:read

Query params:

ParamValorDescripción
includeextrasIncluir lista de extras

Respuesta 200:

{
  "id": "uuid",
  "title": "Tour guiado",
  "slug": "tour-guiado",
  "description": "...",
  "short_description": "...",
  "base_price": 25.00,
  "currency": "EUR",
  "duration_minutes": 120,
  "base_capacity": 4,
  "max_capacity": 10,
  "status": "active",
  "shop_id": "uuid",
  "created_at": "2024-01-15T10:00:00Z",
  "extras": [
    {
      "id": "uuid",
      "name": "Fotos",
      "price": 5.00,
      "description": "..."
    }
  ]
}

GET /experiences/:id/extras

Lista extras de la experiencia.

Scope: experiences:read

Query params:

ParamTipoDefault
limitnumber50
offsetnumber0

Respuesta 200:

{
  "extras": [
    {
      "id": "uuid",
      "name": "Fotos",
      "description": "...",
      "price": 5.00,
      "category": "Servicios",
      "max_quantity": 10
    }
  ]
}

Bookings

GET /bookings

Lista reservas de los shops del partner.

Scope: bookings:read

Query params:

ParamTipoDefaultDescripción
shop_idUUID-Filtrar por shop (debe estar en tus shops)
statusstring-pending, confirmed, completed, cancelled
date_fromstring-Fecha desde (YYYY-MM-DD)
date_tostring-Fecha hasta (YYYY-MM-DD)
limitnumber20Máx 100
offsetnumber0Paginación

Respuesta 200:

{
  "bookings": [
    {
      "id": "uuid",
      "order_id": "uuid",
      "kit_id": "uuid",
      "booking_date": "2024-06-15",
      "booking_time": "10:00:00",
      "number_of_people": 2,
      "total_price": 60.00,
      "status": "pending",
      "created_at": "2024-01-15T10:00:00Z"
    }
  ],
  "total": 42
}

GET /bookings/:id

Detalle de una reserva.

Scope: bookings:read

Respuesta 200:

{
  "id": "uuid",
  "order_id": "uuid",
  "kit_id": "uuid",
  "booking_date": "2024-06-15",
  "booking_time": "10:00:00",
  "number_of_people": 2,
  "price_per_person": 25.00,
  "extras_total": 10.00,
  "total_price": 60.00,
  "status": "pending",
  "selected_extras": [...],
  "special_requests": "...",
  "created_at": "2024-01-15T10:00:00Z",
  "order": { ... },
  "kit": { ... }
}

POST /bookings

Crea una reserva. Requiere header Idempotency-Key.

Scope: bookings:write

Headers:

HeaderRequeridoDescripción
Idempotency-KeySíUUID o string único para evitar duplicados

Body:

{
  "kit_id": "uuid",
  "shop_id": "uuid",
  "booking_date": "2024-06-15",
  "booking_time": "10:00",
  "number_of_people": 2,
  "buyer_name": "Juan Pérez",
  "buyer_email": "juan@ejemplo.com",
  "buyer_phone": "+34600000000",
  "selected_extras": [
    { "extra_id": "uuid", "quantity": 1 }
  ],
  "special_requests": "Sin gluten"
}
CampoTipoRequeridoDescripción
kit_idUUIDSíID de la experiencia
shop_idUUIDSíID del shop (debe estar en tus shops)
booking_datestringSíYYYY-MM-DD
booking_timestringSíHH:mm o HH:mm:ss
number_of_peoplenumberSí1-100
buyer_namestringSíMáx 200
buyer_emailstringSíEmail válido
buyer_phonestringNoMáx 50
selected_extrasarrayNo[{ extra_id, quantity }]
special_requestsstringNoMáx 1000

Nota: Las reservas creadas vía API tienen payment_source: 'external'. El pago no se gestiona en Celebrae.

Restricciones de reservas con payment_source: 'external':

  • No pasan por el checkout de Celebrae; el pago se gestiona fuera de la plataforma.
  • El order tiene payment_status: 'pending' (o 'external'); no se genera flujo de pago CELEBRAE.
  • QR y validación: consulta la documentación del producto para reglas específicas de generación de QR y validación en punto de venta.
  • Notificaciones: se dispara el webhook booking.created para sincronización; las notificaciones por email pueden variar según configuración.
  • Integraciones externas (Turitop, Octo, etc.): pueden tener restricciones adicionales; contacta a soporte si necesitas integración con proveedores externos.

Respuesta 201:

{
  "booking": {
    "id": "uuid",
    "order_id": "uuid",
    "kit_id": "uuid",
    "booking_date": "2024-06-15",
    "booking_time": "10:00:00",
    "number_of_people": 2,
    "total_price": 60.00,
    "status": "pending",
    "created_at": "2024-01-15T10:00:00Z"
  }
}

Idempotencia: Si repites la misma petición con la misma Idempotency-Key y el mismo body, recibirás la misma respuesta sin crear duplicados. Si el body es distinto, recibirás 409 Conflict.


Webhooks

GET /webhooks/deliveries

Lista intentos de envío de webhooks salientes.

Scope: webhooks:read

Query params:

ParamDescripción
event_idFiltrar por evento
endpoint_idFiltrar por endpoint
statuspending, delivered, failed
limit20 (default), máx 100
offset0

Respuesta 200:

{
  "deliveries": [
    {
      "id": "uuid",
      "event_id": "uuid",
      "endpoint_id": "uuid",
      "attempt_number": 1,
      "status": "delivered",
      "response_status": 200,
      "error_message": null,
      "created_at": "2024-01-15T10:00:00Z"
    }
  ],
  "total": 1
}

GET /webhooks/deliveries/:id

Detalle de un intento de envío.

Scope: webhooks:read


POST /webhooks/deliveries/:id/retry

Reintenta manualmente un envío fallido. Solo administradores (sesión Celebrae, no API client).


Webhooks salientes (consumir)

Cuando ocurren eventos (ej. booking.created), Celebrae envía un POST a la URL configurada.

Headers

HeaderDescripción
X-Celebrae-SignatureHMAC-SHA256 de timestamp + "." + body
X-Celebrae-TimestampUnix timestamp (segundos)
X-Celebrae-Event-IdID del evento
X-Celebrae-Idempotency-Key(Opcional) Para deduplicar en tu lado
Content-Typeapplication/json

Verificación de firma

const crypto = require('crypto');
const payload = `${timestamp}.${rawBody}`;
const expected = crypto.createHmac('sha256', secret).update(payload).digest('hex');
const valid = crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));

Eventos

event_typeCuándo
booking.createdSe crea una reserva
booking.updatedSe actualiza una reserva (ej. confirmación)
booking.completedSe marca una reserva como completada
booking.cancelledSe cancela una reserva
*Todos los eventos

Ejemplo de payload (booking.created)

{
  "booking_id": "uuid",
  "order_id": "uuid",
  "kit_id": "uuid",
  "shop_id": "uuid",
  "booking_date": "2024-06-15",
  "booking_time": "10:00",
  "number_of_people": 2,
  "status": "pending",
  "payment_source": "external"
}

Configuración de endpoints

Puedes registrar tus endpoints de webhook vía API (scope webhooks:write):

  • POST /webhooks/endpoints — Crear endpoint. Body: { shop_id, url, events?: ["booking.created", "booking.updated", "booking.completed", "booking.cancelled", "*"] }. Devuelve signing_secret (guárdalo, no se muestra de nuevo).
  • GET /webhooks/endpoints — Listar endpoints. Query: shop_id (opcional).
  • PATCH /webhooks/endpoints/:id — Actualizar URL, eventos o status (active, paused, disabled).
  • DELETE /webhooks/endpoints/:id — Eliminar endpoint.

También puedes gestionarlos desde el panel seller: Mi local → API y webhooks → Webhooks.


Resumen de endpoints

MétodoRutaScope
GET/shopsshops:read
GET/shops/:idshops:read
GET/shops/:id/experiencesexperiences:read
GET/experiences/:idexperiences:read
GET/experiences/:id/extrasexperiences:read
GET/bookingsbookings:read
GET/bookings/:idbookings:read
POST/bookingsbookings:write
GET/webhooks/deliverieswebhooks:read
GET/webhooks/deliveries/:idwebhooks:read