Skip to content

Endpoints

URL base: https://api.zelta.dev/grid/v1

Todos los endpoints requieren autenticacion mediante token Bearer. Consulta la para obtener tu token.

Pantallas (Screens)

Listar pantallas

http
GET /screens

Parametros de consulta:

ParametroTipoDescripcion
pageintegerNumero de pagina (default: 1)
per_pageintegerResultados por pagina (default: 25, max: 100)
statusstringFiltrar por estado: online, offline, standby
group_idstringFiltrar por grupo de pantallas
searchstringBuscar por nombre de pantalla

Ejemplo:

bash
curl -X GET "https://api.zelta.dev/grid/v1/screens?status=online" \
  -H "Authorization: Bearer {token}"

Respuesta:

json
{
  "data": [
    {
      "id": "scr_abc123",
      "name": "Recepcion - Planta Baja",
      "status": "online",
      "orientation": "landscape",
      "resolution": "1920x1080",
      "current_playlist_id": "pl_xyz789",
      "group_id": "grp_001",
      "last_sync": "2026-03-11T14:30:00Z",
      "uptime_hours": 720,
      "created_at": "2026-01-10T09:00:00Z"
    }
  ],
  "meta": {
    "current_page": 1,
    "total_pages": 2,
    "total_count": 15
  }
}

Scope requerido: grid:screens:read

Obtener pantalla

http
GET /screens/{screen_id}

Vincular pantalla

http
POST /screens

Cuerpo de la peticion:

json
{
  "pairing_code": "482715",
  "name": "Vitrina Principal",
  "group_id": "grp_001",
  "orientation": "landscape",
  "location": {
    "name": "Sucursal Centro",
    "address": "Av. Reforma 123, CDMX"
  }
}

Scope requerido: grid:screens:write

Actualizar pantalla

http
PATCH /screens/{screen_id}

Cuerpo de la peticion:

json
{
  "name": "Vitrina Principal - Actualizado",
  "orientation": "portrait",
  "volume": 75,
  "brightness": 80
}

Ejecutar accion remota

http
POST /screens/{screen_id}/actions

Cuerpo de la peticion:

json
{
  "action": "restart_app",
  "reason": "Actualizacion de contenido"
}

Acciones disponibles: restart_app, restart_device, screenshot, force_sync, clear_cache

Desvincular pantalla

http
DELETE /screens/{screen_id}

Scope requerido: grid:screens:write

Atencion

Desvincular una pantalla elimina toda su configuracion, programaciones y analiticas asociadas. El dispositivo mostrara la pantalla de vinculacion nuevamente.


Medios (Media)

Listar medios

http
GET /media

Parametros de consulta:

ParametroTipoDescripcion
pageintegerNumero de pagina (default: 1)
per_pageintegerResultados por pagina (default: 25, max: 100)
typestringFiltrar por tipo: image, video
folder_idstringFiltrar por carpeta
searchstringBuscar por nombre de archivo
tagstringFiltrar por etiqueta

Scope requerido: grid:media:read

Subir medio

http
POST /media

Cuerpo (multipart/form-data):

CampoTipoRequeridoDescripcion
filefileSiArchivo de imagen o video
namestringNoNombre personalizado del archivo
folder_idstringNoID de la carpeta de destino
tagsstring[]NoEtiquetas para organizar el archivo

Ejemplo con curl:

bash
curl -X POST https://api.zelta.dev/grid/v1/media \
  -H "Authorization: Bearer {token}" \
  -F "file=@promo-verano.mp4" \
  -F "name=Promocion Verano 2026" \
  -F "folder_id=fld_promos" \
  -F "tags[]=promocion" \
  -F "tags[]=verano"

Scope requerido: grid:media:write

Obtener medio

http
GET /media/{media_id}

Actualizar medio

http
PATCH /media/{media_id}

Eliminar medio

http
DELETE /media/{media_id}

Eliminacion segura

Si el medio esta siendo utilizado en una playlist o layout activo, la API devolvera un error 409 Conflict. Debes remover el medio de todas las playlists antes de eliminarlo, o usar el parametro force=true.


Playlists

Listar playlists

http
GET /playlists

Parametros de consulta:

ParametroTipoDescripcion
pageintegerNumero de pagina (default: 1)
per_pageintegerResultados por pagina (default: 25, max: 100)
searchstringBuscar por nombre de playlist
screen_idstringFiltrar playlists asignadas a una pantalla

Crear playlist

http
POST /playlists

Cuerpo de la peticion:

json
{
  "name": "Promociones Marzo",
  "items": [
    {
      "media_id": "med_img001",
      "duration": 10,
      "transition": "fade",
      "transition_duration": 1
    },
    {
      "media_id": "med_vid002",
      "transition": "slide",
      "transition_duration": 0.5
    },
    {
      "media_id": "med_img003",
      "duration": 8,
      "transition": "cut"
    }
  ],
  "playback_mode": "loop",
  "shuffle": false
}

Scope requerido: grid:playlists:write

Obtener playlist

http
GET /playlists/{playlist_id}

Respuesta:

json
{
  "id": "pl_xyz789",
  "name": "Promociones Marzo",
  "items": [
    {
      "id": "item_001",
      "media_id": "med_img001",
      "media_name": "Banner principal",
      "media_type": "image",
      "duration": 10,
      "transition": "fade",
      "position": 1
    }
  ],
  "playback_mode": "loop",
  "total_duration": 85,
  "screens_count": 3,
  "created_at": "2026-03-01T10:00:00Z",
  "updated_at": "2026-03-10T15:30:00Z"
}

Actualizar playlist

http
PATCH /playlists/{playlist_id}

Eliminar playlist

http
DELETE /playlists/{playlist_id}

Layouts

Listar layouts

http
GET /layouts

Crear layout

http
POST /layouts

Cuerpo de la peticion:

json
{
  "name": "Ofertas + Redes Sociales",
  "resolution": "1920x1080",
  "zones": [
    {
      "id": "zone_main",
      "x": 0,
      "y": 0,
      "width": "70%",
      "height": "100%",
      "content_type": "playlist",
      "content_id": "pl_xyz789"
    },
    {
      "id": "zone_sidebar",
      "x": "70%",
      "y": 0,
      "width": "30%",
      "height": "100%",
      "content_type": "playlist",
      "content_id": "pl_social456"
    }
  ]
}

Scope requerido: grid:playlists:write

Obtener layout

http
GET /layouts/{layout_id}

Actualizar layout

http
PATCH /layouts/{layout_id}

Eliminar layout

http
DELETE /layouts/{layout_id}

Programaciones (Schedules)

Listar programaciones

http
GET /schedules

Parametros de consulta:

ParametroTipoDescripcion
screen_idstringFiltrar por pantalla
group_idstringFiltrar por grupo
activebooleanSolo programaciones activas
fromdateFecha de inicio (ISO 8601)
todateFecha de fin (ISO 8601)

Crear programacion

http
POST /schedules

Cuerpo de la peticion:

json
{
  "name": "Horario laboral",
  "screen_ids": ["scr_abc123", "scr_def456"],
  "priority": 3,
  "rules": [
    {
      "days": ["monday", "tuesday", "wednesday", "thursday", "friday"],
      "time_start": "09:00",
      "time_end": "18:00",
      "playlist_id": "pl_xyz789"
    },
    {
      "days": ["saturday", "sunday"],
      "time_start": "10:00",
      "time_end": "14:00",
      "playlist_id": "pl_weekend123"
    }
  ],
  "date_range": {
    "start": "2026-03-01",
    "end": "2026-12-31"
  },
  "active": true
}

Scope requerido: grid:schedules:write

Obtener programacion

http
GET /schedules/{schedule_id}

Actualizar programacion

http
PATCH /schedules/{schedule_id}

Eliminar programacion

http
DELETE /schedules/{schedule_id}

Analiticas (Analytics)

Resumen de reproducciones

http
GET /analytics/playback

Parametros de consulta:

ParametroTipoDescripcion
screen_idstringFiltrar por pantalla
media_idstringFiltrar por archivo multimedia
playlist_idstringFiltrar por playlist
fromdateFecha de inicio (ISO 8601)
todateFecha de fin (ISO 8601)
group_bystringAgrupar por: screen, media, playlist, day, hour

Ejemplo:

bash
curl -X GET "https://api.zelta.dev/grid/v1/analytics/playback?from=2026-03-01&to=2026-03-11&group_by=media" \
  -H "Authorization: Bearer {token}"

Respuesta:

json
{
  "data": [
    {
      "media_id": "med_img001",
      "media_name": "Banner principal",
      "total_plays": 1520,
      "total_duration_seconds": 15200,
      "unique_screens": 5,
      "completion_rate": 100
    },
    {
      "media_id": "med_vid002",
      "media_name": "Video promocional",
      "total_plays": 890,
      "total_duration_seconds": 26700,
      "unique_screens": 3,
      "completion_rate": 94.5
    }
  ],
  "meta": {
    "period": {
      "from": "2026-03-01",
      "to": "2026-03-11"
    },
    "total_plays": 2410
  }
}

Scope requerido: grid:analytics:read

Estado de pantallas

http
GET /analytics/screens/status

Respuesta:

json
{
  "total_screens": 15,
  "online": 13,
  "offline": 1,
  "standby": 1,
  "average_uptime_percent": 99.2
}

Grupos (Groups)

Listar grupos

http
GET /groups

Crear grupo

http
POST /groups
json
{
  "name": "Sucursal Centro",
  "description": "Pantallas de la sucursal ubicada en Centro Historico",
  "screen_ids": ["scr_abc123", "scr_def456"]
}

Obtener grupo

http
GET /groups/{group_id}

Actualizar grupo

http
PATCH /groups/{group_id}

Eliminar grupo

http
DELETE /groups/{group_id}

Codigos de respuesta

CodigoDescripcion
200Solicitud exitosa
201Recurso creado exitosamente
204Recurso eliminado exitosamente
400Solicitud mal formada
401No autenticado
403Sin permisos suficientes
404Recurso no encontrado
409Conflicto (ej: medio en uso al intentar eliminar)
422Error de validacion
429Limite de tasa excedido
500Error interno del servidor

Paginacion

Todos los endpoints de listado soportan paginacion. Usa los campos meta.current_page y meta.total_pages de la respuesta para navegar entre paginas. El maximo de resultados por pagina es 100.

Documentación oficial de Zelta