Saltar al contenido
yaReserva

Buscar en el sitio

Ir a

Se busca en las 78 funcionalidades, las 36 guías, la documentación y las preguntas frecuentes.

Agendar

Documentación

Empezar

La API de yaReserva para quien integra un sistema con un hotel: cómo se firma cada petición, cómo se evita cobrar dos veces y qué devuelve cuando algo sale mal.

Qué es esta API

yaReserva es el sistema con el que un hotel opera y vende. Esta API es la puerta para que otro programa haga una parte de ese trabajo: consultar qué hay libre y reservar desde el sitio web del propio hotel, cargar la cena del restaurante a la habitación, o emitir la llave digital al hacer check-in.

No es una API pública de catálogo: cada credencial pertenece a un hotel y a una propiedad suya, y solo ve lo de esa propiedad. El hotel la crea desde su panel y la puede apagar cuando quiera.

IntegraciónPara quiénQuién llama a quién
Motor de reservas propioEl hotel que ya tiene su buscador en su webTu servidor llama a yaReserva
POS de restauranteSoft Restaurant, Parrot, Loyverse u otro punto de ventaEl POS llama a yaReserva
CerradurasSalto, TTLock, Dormakaba, Assa Abloy y el puente del hotelyaReserva llama a tu puente

Dato: Todo lo de esta página aplica a las tres

Cambia el prefijo de los headers y el de la llave, no la mecánica. Lee esta página una vez y después ve directo al apartado de tu integración.

Ambientes

Hay dos ambientes y son dos mundos separados. Las credenciales de uno no sirven en el otro: una llave de pruebas en producción responde 401, y al revés también. El hotel pide las de prueba en su panel y con ellas recibe la URL base contra la que apuntar.

AmbienteURL baseQué pasa ahí
PruebasLa URL base llega con tus credenciales de pruebaDatos de prueba. Ningún cobro real, ninguna cerradura real. Es donde se construye.
Producciónhttps://api.yareserva.comHuéspedes reales y dinero real. El hotel la habilita cuando su integración ya funciona en pruebas.

Guarda la URL base en tu configuración, nunca en el código. Pasar de pruebas a producción tiene que ser cambiar dos valores: la URL y el par de credenciales.

Autenticación por firma

No hay tokens ni sesiones. Cada petición se firma por separado con el secreto de la conexión, y el secreto nunca viaja: lo que viaja es la firma, que es lo único que se puede calcular teniéndolo.

Cada integración tiene su terna de headers. Cambia el nombre, no la forma: llave pública, hora y firma.

IntegraciónPrefijo de la llaveHeaders
Motor de reservasyreng_X-YR-ENG-Key, X-YR-ENG-Timestamp, X-YR-ENG-Signature
POS de restauranteyrpos_X-YR-POS-Key, X-YR-POS-Timestamp, X-YR-POS-Signature
Cerradurasyrlock_X-YR-Lock-Key, X-YR-Lock-Timestamp, X-YR-Lock-Signature
  1. Serializa el cuerpo a JSON y quédate con esos bytes exactos. A partir de aquí no lo vuelvas a formatear: un espacio de más cambia la firma.
  2. Toma la hora actual en segundos Unix, en UTC. Ese número es el timestamp.
  3. Arma la cadena a firmar concatenando el timestamp, un punto y el cuerpo: «timestamp + "." + cuerpo». En un GET el cuerpo es vacío, así que la cadena termina en el punto.
  4. Calcula HMAC-SHA256 de esa cadena usando el secreto como llave, y pásalo a hexadecimal en minúsculas.
  5. Manda los tres headers: la llave pública, el timestamp que usaste y la firma con el prefijo «sha256=».
Los headers, ya armados
X-YR-ENG-Key:       yreng_3f9a1c0b7d2e4a6f8b0c1d2e
X-YR-ENG-Timestamp: 1789459391
X-YR-ENG-Signature: sha256=9c1f0a7d4b2e6c8a1f3d5b7e9c0a2d4f6b8e0c2a4d6f8b0c2e4a6d8f0b2c4e6a
bash
KEY=yreng_3f9a1c0b7d2e4a6f8b0c1d2e
SECRET=yreng_sk_...
BODY='{"offers":["eyJ2IjoxLCJyIjoi..."],"guest":{"firstName":"Ana","lastName":"Ruiz","email":"ana@correo.mx"},"acceptedTerms":true,"acceptedPrivacy":true}'
TS=$(date +%s)
SIG=$(printf '%s.%s' "$TS" "$BODY" | openssl dgst -sha256 -hmac "$SECRET" -hex | sed 's/^.* //')

curl -X POST https://api.yareserva.com/api/v1/engine/bookings \
  -H "Content-Type: application/json" \
  -H "X-YR-ENG-Key: $KEY" \
  -H "X-YR-ENG-Timestamp: $TS" \
  -H "X-YR-ENG-Signature: sha256=$SIG" \
  -H "X-Idempotency-Key: 8c2e1f04-5a6b-4c7d-8e9f-0a1b2c3d4e5f" \
  --data-binary "$BODY"
Node.js
const crypto = require('crypto');

function firmar(payload, secret) {
  const body = JSON.stringify(payload);
  const ts = Math.floor(Date.now() / 1000).toString();
  const sig = crypto.createHmac('sha256', secret).update(`${ts}.${body}`).digest('hex');
  return { body, ts, sig: `sha256=${sig}` };
}

// Manda `body` tal cual, sin volver a serializar el objeto.
Python
import hashlib, hmac, json, time

def firmar(payload, secret):
    body = json.dumps(payload, separators=(",", ":")).encode()
    ts = str(int(time.time()))
    sig = hmac.new(secret.encode(), ts.encode() + b"." + body, hashlib.sha256).hexdigest()
    return body, ts, "sha256=" + sig

Regla: El secreto se ve una sola vez

Al crear la conexión o al rotarla, el panel enseña el secreto una vez y no lo vuelve a enseñar: se guarda cifrado y ni el hotel ni nosotros lo podemos leer después. Guárdalo en tu gestor de secretos en ese momento. Si se pierde, la salida es rotar, y el secreto anterior deja de valer en el acto.

El timestamp caduca

Una firma válida sigue siendo válida para siempre si nadie mira la hora. Por eso la miramos: el timestamp que mandas no puede diferir del nuestro en más de cinco minutos. Fuera de ese margen la petición se rechaza aunque la firma esté bien.

  • Sincroniza el reloj del servidor con NTP. El 401 más común no es una firma mal calculada, es un reloj atrasado.
  • Genera un timestamp y una firma nuevos en cada reintento. Reenviar la petición completa tal cual falla en cuanto pasan cinco minutos.
  • La hora va en segundos, no en milisegundos. Un valor en milisegundos queda miles de años en el futuro y se rechaza.

Idempotencia

Una red que se corta no te dice si la petición llegó. Reintentar a ciegas es lo que duplica una reserva o cobra dos veces la misma cena. Por eso todo lo que crea algo lleva una llave de idempotencia.

Código en http
X-Idempotency-Key: 8c2e1f04-5a6b-4c7d-8e9f-0a1b2c3d4e5f
  • Genera la llave una vez, antes del primer intento, y reúsala en todos los reintentos de esa misma operación. Un UUID v4 sirve.
  • La misma llave devuelve el mismo resultado: el recurso que ya se creó, no uno nuevo y no un error.
  • La llave queda anotada junto al recurso que creó. Reusarla con datos distintos no crea nada nuevo ni da error: devuelve el primero. Si cambian los datos, cambia la llave.
  • La llave admite letras, dígitos y . _ : - y cabe en 100 caracteres. Un UUID v4 sirve.
  • La comprobación de la llave y la venta ocurren dentro de un lock, así que dos peticiones simultáneas con la misma llave no pueden crear dos recursos: se serializan.

Dato: El POS usa el folio del ticket

En los cargos a la habitación el papel de la llave de idempotencia lo hace el campo «externalId», que es el folio del ticket del restaurante. Es la misma idea con otro nombre: reintenta con el mismo folio y el cargo no se duplica.

Formato de las respuestas

Toda respuesta es JSON con la misma envoltura. Cuando salió bien viene «data»; cuando no, viene «error». Nunca los dos. «meta» aparece solo en las listas paginadas.

Salió bien
{
  "data": {
    "id": "5d0c3f1e-2b7a-4c1d-9e8f-0a1b2c3d4e5f",
    "totalCents": 372000,
    "currency": "MXN",
    "createdAt": "2026-11-20T21:03:11Z"
  },
  "meta": { "page": 1, "limit": 20, "total": 37 }
}
Salió mal
{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "checkOut must be after checkIn",
    "details": { "field": "checkOut" }
  }
}
QuéCómo viajaEjemplo
IdentificadoresUUID v4 en texto. Nunca enteros.5d0c3f1e-2b7a-4c1d-9e8f-0a1b2c3d4e5f
MomentosISO 8601 en UTC, con la Z al final.2026-11-20T21:03:11Z
DíasAAAA-MM-DD, sin hora. Una entrada es un día, no un instante.2026-11-20
ImportesCentavos, siempre entero y siempre con su moneda.372000 MXN son $3,720.00
ErroresEl código es estable y en inglés; el mensaje va en español, para que lo puedas enseñar tal cual.code: OFFER_EXPIRED

Cuidado: Los centavos no se convierten a decimal por el camino

Divide entre cien solo al pintar en pantalla. Si guardas el importe como número con punto decimal, tarde o temprano un redondeo deja un peso de diferencia entre tu ticket y el folio del huésped.

Errores

El código HTTP dice de qué tipo es el problema y «error.code» dice cuál exactamente. Programa contra el código, no contra el texto del mensaje: el mensaje está para leerlo una persona y puede cambiar.

Errores

HTTPCódigoCuándoQué hacer
400IDEMPOTENCY_KEY_REQUIREDFalta la llave de idempotencia en algo que crea un recurso.Mándala. No se inventa por ti.
401INVALID_SIGNATURELlave desconocida o revocada, firma que no cuadra, u hora fuera del margen de cinco minutos.Revisa el reloj primero. Después, que firmes los bytes exactos que mandas.
403ORIGIN_NOT_ALLOWEDLa petición llegó desde un navegador con un dominio que la llave no tiene autorizado.No reintentes. O llamas desde tu servidor, o el hotel declara ese dominio en su panel.
404NOT_FOUNDEl recurso no existe, o no es de esta propiedad.Comprueba el identificador. Una credencial solo ve su propiedad.
409(varios)La operación choca con el estado actual: ya se canceló, ya se cobró, ya no admite cargos. Cada integración tiene sus códigos, y están en su apartado.Lee el recurso para ver cómo quedó antes de decidir. Reintentar igual vuelve a chocar.
413PAYLOAD_TOO_LARGEEl cuerpo pasa de 64 KB.Manda menos líneas o menos detalle.
422VALIDATION_ERRORFalta un campo o trae un valor imposible.«details.field» dice cuál. Corrígelo y vuelve a mandar.
429RATE_LIMIT_EXCEEDEDMás de 300 peticiones por minuto desde la misma IP.Espera lo que diga «Retry-After» y reintenta. Es el único 4xx que se reintenta sin cambiar nada.
500INTERNAL_ERRORAlgo se rompió de nuestro lado.Reintenta con la misma llave de idempotencia, espaciando los intentos.
503PAYMENTS_NOT_CONFIGUREDEl hotel no tiene el cobro en línea configurado.No reintentes. Todo lo demás sigue funcionando; lo único que no se puede es cobrar.

Regla: Nunca guardes datos de tarjeta

Ningún endpoint de esta API recibe un número de tarjeta, un CVV ni una fecha de vencimiento, y ninguno los devuelve. El dato de la tarjeta lo toma Stripe en el navegador del huésped y nunca pasa por tu sistema ni por el nuestro.

¿Vas a integrar un hotel?

Las credenciales salen del panel del hotel, y las de sandbox se crean el mismo día. Si el hotel todavía no tiene cuenta, empieza por registrarlo.