AppToIn Connect v1.1.1

Introducción

La AppToIn Connect expone los datos y operaciones de AppToIn para integraciones externas. Permite autenticarse mediante API Key o sesión y gestionar escenas e invitaciones respetando los permisos asignados a cada clave.

Base URL:

http://connect.apptoin.com

Todos los endpoints devuelven JSON. En las respuestas de éxito siempre aparece "ok": true; en error "ok": false junto con un campo "error".

Autenticación

Incluye la API Key en la cabecera Authorization de cada petición. Es autenticación stateless (no requiere sesión ni login previo).

Authorization: Bearer <tu-api-key>

Las API Keys se gestionan en AppToIn Manager (Perfil → API Keys). Una clave sin escenas asignadas da acceso a todas las del usuario.

Errores comunes

HTTPerrorDescripción
401UNAUTHORIZEDToken o sesión inválidos
403FORBIDDENAPI Key sin acceso al recurso
404NOT_FOUNDEl recurso no existe
400NO_FIELDSSin campos actualizables en el PUT
400CODIGO_REQUIREDFalta el campo codigo en el PUT de código
400CODIGO_INVALIDPIN no numérico o fuera del rango 4–10 dígitos
400CODIGO_TECLADO_INVALIDPIN en creación: no numérico o fuera de rango
400CODIGO_TECLADO_LONGITUDPIN demasiado corto para una cerradura de la escena
400CODIGO_TECLADO_CEROSPIN contiene ceros y la cerradura no los admite
400CODIGO_TECLADO_PREFIJOPIN empieza por "12" (no permitido por Nuki)
500Error interno

Listar escenas

GET /api/v1/escenas/ Escenas accesibles por la clave

Devuelve solo las escenas autorizadas para la API Key. Sin escenas asignadas devuelve todas las del usuario.

200 OK
{
  "ok": true,
  "escenas": [
    {
      "id": 42,
      "nombre": "Apartamento Centro",
      "descripcion": "Primer piso, puerta derecha",
      "lat": "40.416775",
      "lon": "-3.703790",
      "direccion": "Calle Gran Vía 1, Madrid",
      "activo": 1
    }
  ]
}

curl

curl http://connect.apptoin.com/api/v1/escenas/ \
  -H "Authorization: Bearer <api-key>"

Detalle de escena

GET /api/v1/escenas/{id}/ Datos completos de una escena
200 OK
{
  "ok": true,
  "escena": {
    "id": 42,
    "nombre": "Apartamento Centro",
    "descripcion": "Primer piso, puerta derecha",
    "lat": "40.416775",
    "lon": "-3.703790",
    "direccion": "Calle Gran Vía 1, Madrid",
    "activo": 1,
    "telefono": "612345678",
    "whatsapp": "612345678",
    "wifi": "MiRed_5G",
    "wifi_password": "clave1234",
    "hora_desde": "15:00",
    "hora_hasta": "11:00",
    "duracion_minima": 1,
    "duracion_maxima": 30,
    "acceso_sin_registro": false,
    "campos_personalizados": [
      { "nombre_campo": "Instrucciones acceso", "tipo_campo": "textarea", "valor_campo": "Pulsa 3 veces el timbre" }
    ],
    "documentos": [
      {
        "id": 12,
        "nombre": "Manual de la casa.pdf",
        "url": "https://multimedia.apptoin.com/banners/imagen/42/abc123.pdf/attachment",
        "mostrar_app": true,
        "adjuntar_invitacion": true
      }
    ],
    "enlaces": [
      {
        "id": 8,
        "nombre": "Taxi 24H",
        "url": "https://taxi24h.es",
        "mostrar_app": true,
        "adjuntar_invitacion": false
      }
    ]
  }
}
curl http://connect.apptoin.com/api/v1/escenas/42/ \
  -H "Authorization: Bearer <api-key>"

Listar invitaciones de escena

GET /api/v1/escenas/{id}/invitaciones/ Invitaciones con filtros opcionales

Query params opcionales

ParámetroTipoDescripción
referenciastringFiltrar por referencia exacta
activo0 | 1Filtrar por activo
desdeYYYY-MM-DDfecha_hasta ≥ desde (mínimo: ayer)
hastaYYYY-MM-DDfecha_desde ≤ hasta
💡 El parámetro desde tiene un mínimo de ayer — no es posible buscar invitaciones que hayan expirado hace más de un día.
200 OK
{
  "ok": true,
  "invitaciones": [
    {
      "id": 100,
      "codigo": "abc12def",
      "fecha_desde": "2025-08-01",
      "hora_desde": "15:00",
      "fecha_hasta": "2025-08-07",
      "hora_hasta": "11:00",
      "referencia": "Reserva #1234",
      "activo": 1,
      "usos": 0,
      "tipoinvitacion_id": 1,
      "url_acceso_directo": "https://key.apptoin.com/invitacion/abc12def/3fa8..."
    }
  ]
}

curl

curl "http://connect.apptoin.com/api/v1/escenas/42/invitaciones/?referencia=RES-1234" \
  -H "Authorization: Bearer <api-key>"

Crear invitación

POST /api/v1/escenas/{id}/invitaciones/ Nueva invitación para la escena
CampoTipoReq.Descripción
fecha_desdeYYYY-MM-DDInicio del acceso (defecto: hoy)
hora_desdeHH:MMHora de inicio (defecto: hora de la escena)
fecha_hastaYYYY-MM-DDFin del acceso (defecto: mañana)
hora_hastaHH:MMHora de fin (defecto: hora de la escena)
referenciastringReferencia de reserva
observacionesstringNotas internas
usosintegerMáx. usos (defecto: 4, máximo: 10)
tipoinvitacion_idintegerTipo de invitación — ver tabla ↓ (defecto: 1)
plataforma_idintegerPlataforma de origen — ver tabla ↓ (defecto: 1)
contactostringEmail o teléfono del huésped
idiomastringCódigo de idioma del contacto — ver tabla ↓ (defecto: es)
tipocheckinintegerTipo de checkin — ver tabla ↓ (solo si la escena tiene checkin)
numero_checkinsintegerNº de huéspedes (solo si la escena tiene checkin configurado)
codigo_tecladostring (4–10 dígitos)PIN personalizado para todos los teclados. Si se omite, el sistema genera uno automático.
activobooleanEstado inicial (defecto: true)

tipoinvitacion_id

idDescripción
1Estancia (defecto)
2Pase

plataforma_id

idPlataforma
1Sin definir (defecto)
2Airbnb
3Booking
4Expedia
5Otra
6Web

tipocheckin

valorDescripción
0Sin checkin
2Checkin completo

idioma

códigoIdioma
esEspañol (defecto)
enEnglish
frFrançais
ptPortuguês
itItaliano
deDeutsch
💡 Si la escena no tiene checkin configurado, los campos tipocheckin y numero_checkins se ignoran.
💡 Si la escena tiene acceso sin registro habilitado, la respuesta incluye url_acceso_directo con el enlace directo que puedes enviar al huésped.
⚠ Restricciones del PIN: solo dígitos; cada cerradura puede tener longitud mínima requerida o restricciones adicionales (p.ej. Nuki no admite ceros ni el prefijo "12").
201 Created
{
  "ok": true,
  "invitacion": {
    "id": 101,
    "codigo": "xyz9abc1",
    "fecha_desde": "2026-07-01",
    "hora_desde": "15:00",
    "fecha_hasta": "2026-07-05",
    "hora_hasta": "11:00",
    "referencia": "RES-1234",
    "activo": 1,
    "usos": 4,
    "url_acceso_directo": "https://key.apptoin.com/invitacion/xyz9abc1/3fa85f64...",
    "codigos_teclado": [
      {
        "id": 55,
        "codigo": "881234",
        "estado": 0,
        "estado_label": "pendiente",
        "activo": 1,
        "cerradura_id": 6,
        "cerradura_nombre": "Puerta principal",
        "tipocerradura_id": 2
      }
    ]
  }
}
400 — Errores de PIN
{ "ok": false, "error": "CODIGO_TECLADO_INVALID" }             // no es numérico o fuera de rango 4–10
{ "ok": false, "error": "CODIGO_TECLADO_LONGITUD", "tipo": "Nuki" }  // muy corto para ese teclado
{ "ok": false, "error": "CODIGO_TECLADO_CEROS",    "tipo": "Nuki" }  // ese teclado no admite ceros
{ "ok": false, "error": "CODIGO_TECLADO_PREFIJO",  "tipo": "Nuki" }  // ese teclado no admite el prefijo "12"

curl

curl -X POST http://connect.apptoin.com/api/v1/escenas/42/invitaciones/ \
  -H "Authorization: Bearer <api-key>" \
  -H "Content-Type: application/json" \
  -d '{
    "referencia": "Reserva #1234",
    "contacto": "huesped@email.com",
    "usos": 2
  }'

Detalle de invitación

GET /api/v1/invitaciones/{id}/ Datos + códigos de teclado

La respuesta incluye codigos_teclado[], campos_personalizados[], usuarios[] (cada uno con sus propios campos_personalizados[]) y, si la escena tiene acceso sin registro, url_acceso_directo.

curl http://connect.apptoin.com/api/v1/invitaciones/100/ \
  -H "Authorization: Bearer <api-key>"
200 OK
{
  "ok": true,
  "invitacion": {
    "id": 100,
    "codigo": "abc12def",
    "referencia": "RES-1234",
    "fecha_desde": "2026-07-01",
    "hora_desde": "15:00",
    "fecha_hasta": "2026-07-05",
    "hora_hasta": "11:00",
    "activo": 1,
    "usos": 4,
    "url_acceso_directo": "https://key.apptoin.com/invitacion/abc12def/3fa85f64...",
    "codigos_teclado": [
      { "id": 55, "codigo": "881234", "estado": 0, "estado_label": "pendiente",
        "cerradura_id": 6, "cerradura_nombre": "Puerta principal", "tipocerradura_id": 2 }
    ],
    "campos_personalizados": [
      { "nombre_campo": "Origen", "tipo_campo": "list", "valor_campo": "web", "valor_texto": "Web" }
    ],
    "usuarios": [
      {
        "id": 201, "contacto": "huesped@email.com", "idioma": "es",
        "campos_personalizados": []
      }
    ]
  }
}

Actualizar invitación

PUT /api/v1/invitaciones/{id}/ Actualiza campos (PATCH también aceptado)

Envía solo los campos a modificar: fecha_desde, hora_desde, fecha_hasta, hora_hasta, referencia, observaciones, activo, usos, tipoinvitacion_id.

curl -X PUT http://connect.apptoin.com/api/v1/invitaciones/100/ \
  -H "Authorization: Bearer <api-key>" \
  -H "Content-Type: application/json" \
  -d '{"fecha_hasta":"2025-08-10","hora_hasta":"12:00"}'

Eliminar invitación

DELETE /api/v1/invitaciones/{id}/ Soft delete (activo = 0)
⚠ Las invitaciones no se borran físicamente; se marcan con activo = 0.
curl -X DELETE http://connect.apptoin.com/api/v1/invitaciones/100/ \
  -H "Authorization: Bearer <api-key>"
200 OK
{ "ok": true }

Listar códigos de teclado

GET /api/v1/invitaciones/{id}/codigos/ Códigos y estado de cada cerradura

También incluidos en la respuesta de GET detalle como codigos_teclado.

200 OK
{
  "ok": true,
  "codigos": [
    {
      "id": 12,
      "codigo": "881815",
      "estado": 3,
      "estado_label": "activo",
      "activo": 1,
      "cerradura_id": 2,
      "cerradura_nombre": "Puerta principal",
      "tipocerradura_id": 1
    }
  ]
}

Estados

estadoestado_labelDescripción
0pendienteEn cola para programar
2canceladoEliminado del teclado
3/4activoRegistrado en el teclado físico
5errorFallo al programar
6pendiente_modificacionCambio pendiente
7error_duplicadoCódigo duplicado
8sin_conexionTeclado no alcanzable
curl http://connect.apptoin.com/api/v1/invitaciones/100/codigos/ \
  -H "Authorization: Bearer <api-key>"

Cambiar código de teclado

PUT /api/v1/invitaciones/{id}/codigos/{codigoId}/ Actualiza el PIN de una cerradura
💡 Si el código ya estaba activo (estado 3 o 4), se marca como pendiente_modificacion (estado 6) y el cron de AppToIn lo actualiza en el teclado físico. Si estaba en error, se reintenta (estado 0).
CampoTipoReq.Descripción
codigostring (4–10 dígitos)Nuevo PIN numérico
200 OK
{
  "ok": true,
  "codigo": {
    "id": 12, "codigo": "123456",
    "estado": 6, "estado_label": "pendiente_modificacion",
    "cerradura_nombre": "Puerta principal"
  }
}
400
{ "ok": false, "error": "CODIGO_INVALID" }   // numérico, 4–10 dígitos
{ "ok": false, "error": "CODIGO_REQUIRED" }  // falta el campo
curl -X PUT http://connect.apptoin.com/api/v1/invitaciones/100/codigos/12/ \
  -H "Authorization: Bearer <api-key>" \
  -H "Content-Type: application/json" \
  -d '{"codigo":"123456"}'

Colección Postman

Descarga la colección preconfigurada con todos los endpoints y variables de entorno (base_url, api_key, escena_id, etc.).

↓ Descargar colección Postman

Importa en Postman: File → Import → selecciona el .json. Edita las variables de colección con tus credenciales.