Referencia · Reservas

Crear una reserva de uno a ocho turnos

POST /api/v1/reservas

Ver en Markdown
POST/api/v1/reservas

Scope reservas:crear. Exige Idempotency-Key: misma clave y mismo cuerpo devuelven la misma reserva (200, operacion.repetida: true); otro cuerpo con la misma clave da 409 CONFLICTO_INTENCION. Con seña, la reserva queda GUARDADO con pago: PENDIENTE y datos.sena.checkoutUrl (Mercado Pago); se confirma solo por el webhook de MP.

Autenticación: Authorization: Bearer <clave>. Ver Autenticación.

Parámetros

NombreEnTipoObligatorioDescripción
Idempotency-KeyheaderstringSíFormato ^[A-Za-z0-9._:-]{8,100}$.

Cuerpo

CampoTipoObligatorioDescripción
turnosarray de objectSíEntre 1 y 8 elementos.
turnos[].servicioIdstringSí
turnos[].varianteIdstring o nullNo
turnos[].profesionalIdstring o nullNo
turnos[].fechastring (date)Sí
turnos[].horastringSíHora del negocio. Formato ^(?:[01]\d|2[0-3]):[0-5]\d$.
turnos[].addOnIdsarray de stringNoEntre 0 y 50 elementos.
sucursalIdstring o nullNo
modoCadena"uno_tras_otro"No
clienteobjectSí
cliente.nombrestringSíHasta 120 caracteres.
cliente.telefonostringSíHasta 32 caracteres.
cliente.codigoPaisstringNoHasta 6 caracteres. Por defecto +54.
cliente.emailstringNoHasta 254 caracteres.
cliente.consintioContactobooleanNo
notasstringNoHasta 4000 caracteres.
cuponCodigostringNoHasta 64 caracteres.

Ejemplo

curl -X POST "https://turnovapp.com/api/v1/reservas" \
  -H "Authorization: Bearer $TURNOVA_CLAVE_SECRETA" \
  -H "Idempotency-Key: reserva-7f3c2a9e-01" \
  -H "Content-Type: application/json" \
  -d '{ "turnos": [ { "servicioId": "cmh3s0abc0012", "fecha": "2030-01-10", "hora": "10:00" } ], "cliente": { "nombre": "Ana Pérez", "telefono": "+5493515550101", "email": "[email protected]" } }'

Respuestas

HTTPQué significa
200Reintento de una reserva ya hecha con la misma clave
201Reserva nueva
400Datos inválidos: mirá error.campos (ENTRADA_INVALIDA, IDEMPOTENCY_KEY_FALTANTE…).
401Clave faltante, inválida o revocada.
403Origen no permitido, permiso faltante, clave secreta desde un navegador o plan sin la API (PLAN_SIN_API).
404No existe o no es de este negocio.
409Conflicto: el horario ya no está libre, otra intención con la misma Idempotency-Key o el servicio se reserva por WhatsApp.
429Demasiados pedidos (LIMITE_USO): esperá Retry-After segundos.
500Error técnico: reintentá con los mismos datos (y la misma Idempotency-Key).

Respuesta 201

{
  "version": 1,
  "ok": true,
  "progreso": {
    "principal": "GUARDADO",
    "pago": "PENDIENTE"
  },
  "operacion": {
    "referencia": "cmh4k2n9x0001",
    "repetida": false
  },
  "requiereRevision": false,
  "datos": {
    "compraId": "cmh4k2n9x0001",
    "total": 25000,
    "sena": {
      "monto": 6250,
      "checkoutUrl": "https://www.mercadopago.com.ar/checkout/v1/redirect?pref_id=123456-abcd"
    },
    "turnos": [
      {
        "turnoId": "cmh4k2pa10003",
        "servicio": "Masaje descontracturante",
        "profesional": "Lucía",
        "fecha": "2030-01-10",
        "hora": "10:00",
        "duracionMin": 60,
        "extras": [],
        "sesionesTotal": null
      }
    ]
  }
}
CampoTipoObligatorioDescripción
datos.compraIdstringNo
datos.totalnumberNo
datos.senaobject o nullNo
datos.sena.montonumberNo
datos.sena.checkoutUrlstring o nullNoLink de Mercado Pago. MP vuelve a la página de resultado de Turnova.
datos.turnosarray de objectNo
datos.turnos[].turnoIdstringNo
datos.turnos[].serviciostringNo
datos.turnos[].profesionalstringNo
datos.turnos[].fechastring (date)No
datos.turnos[].horastringNo
datos.turnos[].duracionMinintegerNo
datos.turnos[].extrasarray de stringNo
datos.turnos[].sesionesTotalinteger o nullNo

Los errores siguen el formato común: ver Errores.