@reveldigital/mcp-graphql-proxy 1.19.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,6 +3,753 @@ schema {
3
3
  mutation: Mutation
4
4
  }
5
5
 
6
+ type Query {
7
+ """
8
+ Get play logs - records of when media content was played on devices.
9
+ Useful for tracking content playback history and calculating media impressions.
10
+ """
11
+ playLogs(
12
+ "Optional list of device IDs to filter by"
13
+ deviceId: [String!]
14
+ "Optional list of file IDs to filter by"
15
+ fileId: [String!]
16
+ "Start date for the query (required)"
17
+ startDate: DateTime!
18
+ "End date for the query (required)"
19
+ endDate: DateTime!
20
+ "Maximum number of results (default: 1000, max: 10000)"
21
+ limit: Int! = 1000
22
+ where: AdHawkPlayLogFilterInput @cost(weight: "10")
23
+ order: [AdHawkPlayLogSortInput!] @cost(weight: "10")
24
+ ): [AdHawkPlayLog] @cost(weight: "10")
25
+ """
26
+ Get ping logs - device heartbeat/health data including CPU, memory, and disk usage.
27
+ Useful for monitoring device health and identifying performance issues.
28
+ Example: Find devices with average CPU usage over 90%.
29
+ """
30
+ pingLogs(
31
+ "Optional list of device IDs to filter by"
32
+ deviceId: [String!]
33
+ "Optional list of ping types to filter by (1=alive, 2=downloading, 4=playing)"
34
+ type: [Int!]
35
+ "Optional minimum CPU usage percentage to filter by"
36
+ minCpuUsage: Float
37
+ "Optional minimum memory usage percentage to filter by"
38
+ minMemoryUsage: Float
39
+ "Start date for the query (required)"
40
+ startDate: DateTime!
41
+ "End date for the query (required)"
42
+ endDate: DateTime!
43
+ "Maximum number of results (default: 1000, max: 10000)"
44
+ limit: Int! = 1000
45
+ where: AdHawkPingLogFilterInput @cost(weight: "10")
46
+ order: [AdHawkPingLogSortInput!] @cost(weight: "10")
47
+ ): [AdHawkPingLog] @cost(weight: "10")
48
+ """
49
+ Get event logs - custom events generated by devices or applications.
50
+ Useful for tracking user interactions, button clicks, page views, etc.
51
+ """
52
+ eventLogs(
53
+ "Optional list of device IDs to filter by"
54
+ deviceId: [String!]
55
+ "Optional list of event names to filter by"
56
+ eventName: [String!]
57
+ "Optional session ID to filter by"
58
+ sessionId: String
59
+ "Start date for the query (required)"
60
+ startDate: DateTime!
61
+ "End date for the query (required)"
62
+ endDate: DateTime!
63
+ "Maximum number of results (default: 1000, max: 10000)"
64
+ limit: Int! = 1000
65
+ where: AdHawkEventLogFilterInput @cost(weight: "10")
66
+ order: [AdHawkEventLogSortInput!] @cost(weight: "10")
67
+ ): [AdHawkEventLog] @cost(weight: "10")
68
+ """
69
+ Get aggregated event metrics for devices over a time period.
70
+ Useful for analyzing event patterns, user engagement, and interaction trends.
71
+ Metrics include total events, unique sessions, and event breakdowns.
72
+ """
73
+ eventMetrics(
74
+ "Optional list of device IDs to filter by"
75
+ deviceId: [String!]
76
+ "Optional list of event names to filter by"
77
+ eventName: [String!]
78
+ "Time interval for aggregation (minute, hour, day, week, month)"
79
+ interval: AdHawkIntervalType! = DAY
80
+ "Group results by device (default: true)"
81
+ groupByDevice: Boolean! = false
82
+ "Group results by event name (default: false)"
83
+ groupByEvent: Boolean! = false
84
+ "Start date for the query (required)"
85
+ startDate: DateTime!
86
+ "End date for the query (required)"
87
+ endDate: DateTime!
88
+ "Maximum number of results (default: 1000, max: 10000)"
89
+ limit: Int! = 1000
90
+ where: AdHawkEventMetricsFilterInput @cost(weight: "10")
91
+ order: [AdHawkEventMetricsSortInput!] @cost(weight: "10")
92
+ ): [AdHawkEventMetrics] @cost(weight: "10")
93
+ """
94
+ Get impressions - audience detection data from sensors (motion, face detection, BLE, WiFi).
95
+ Useful for analyzing visitor demographics, dwell time, and traffic patterns.
96
+ """
97
+ impressions(
98
+ "Optional list of device IDs to filter by"
99
+ deviceId: [String!]
100
+ "Optional list of impression types to filter by (8=motion, 64=audience, 128=ble, 256=wifi)"
101
+ type: [Int!]
102
+ "Optional gender to filter by"
103
+ gender: AdHawkGender
104
+ "Optional minimum dwell time in milliseconds"
105
+ minDwellTime: Long
106
+ "Start date for the query (required)"
107
+ startDate: DateTime!
108
+ "End date for the query (required)"
109
+ endDate: DateTime!
110
+ "Maximum number of results (default: 1000, max: 10000)"
111
+ limit: Int! = 1000
112
+ where: AdHawkImpressionFilterInput @cost(weight: "10")
113
+ order: [AdHawkImpressionSortInput!] @cost(weight: "10")
114
+ ): [AdHawkImpression] @cost(weight: "10")
115
+ """
116
+ Get aggregated device health metrics over a time period.
117
+ Useful for monitoring fleet health, identifying problematic devices, and capacity planning.
118
+ Metrics include CPU, memory, disk usage, and network traffic.
119
+ """
120
+ deviceMetrics(
121
+ "Optional list of device IDs to filter by"
122
+ deviceId: [String!]
123
+ "Time interval for aggregation (minute, hour, day, week, month)"
124
+ interval: AdHawkIntervalType! = DAY
125
+ "Start date for the query (required)"
126
+ startDate: DateTime!
127
+ "End date for the query (required)"
128
+ endDate: DateTime!
129
+ "Maximum number of results (default: 1000, max: 10000)"
130
+ limit: Int! = 1000
131
+ where: AdHawkDeviceMetricsFilterInput @cost(weight: "10")
132
+ order: [AdHawkDeviceMetricsSortInput!] @cost(weight: "10")
133
+ ): [AdHawkDeviceMetrics] @cost(weight: "10")
134
+ """
135
+ Get aggregated audience metrics for devices over a time period.
136
+ Useful for analyzing visitor demographics, traffic patterns, and engagement.
137
+ Metrics include impressions, unique visitors, dwell time, gender, and age breakdowns.
138
+ """
139
+ audienceMetrics(
140
+ "Optional list of device IDs to filter by"
141
+ deviceId: [String!]
142
+ "Time interval for aggregation (minute, hour, day, week, month)"
143
+ interval: AdHawkIntervalType! = DAY
144
+ "Group results by device (default: false)"
145
+ groupByDevice: Boolean! = false
146
+ "When true, queries exit events with dwell time data. When false (default), queries enter events without dwell time."
147
+ includeDwellTime: Boolean! = false
148
+ "Start date for the query (required)"
149
+ startDate: DateTime!
150
+ "End date for the query (required)"
151
+ endDate: DateTime!
152
+ "Maximum number of results (default: 1000, max: 10000)"
153
+ limit: Int! = 1000
154
+ where: AdHawkAudienceMetricsFilterInput @cost(weight: "10")
155
+ order: [AdHawkAudienceMetricsSortInput!] @cost(weight: "10")
156
+ ): [AdHawkAudienceMetrics] @cost(weight: "10")
157
+ """
158
+ Get media play statistics - aggregated play counts and durations for media files.
159
+ Useful for analyzing content performance and identifying popular media.
160
+ """
161
+ mediaPlayStats(
162
+ "Optional list of device IDs to filter by"
163
+ deviceId: [String!]
164
+ "Optional list of file IDs to filter by"
165
+ fileId: [String!]
166
+ "Start date for the query (required)"
167
+ startDate: DateTime!
168
+ "End date for the query (required)"
169
+ endDate: DateTime!
170
+ "Maximum number of results (default: 100, max: 10000)"
171
+ limit: Int! = 100
172
+ where: AdHawkMediaPlayStatsFilterInput @cost(weight: "10")
173
+ order: [AdHawkMediaPlayStatsSortInput!] @cost(weight: "10")
174
+ ): [AdHawkMediaPlayStats] @cost(weight: "10")
175
+ """
176
+ Get device play statistics - aggregated play counts and duration for each device.
177
+ Useful for DooH reporting to analyze device performance and content distribution.
178
+ Example: Find which devices played the most content in a date range.
179
+ """
180
+ devicePlayStats(
181
+ "Optional list of device IDs to filter by"
182
+ deviceId: [String!]
183
+ "Optional list of file IDs to filter by"
184
+ fileId: [String!]
185
+ "Start date for the query (required)"
186
+ startDate: DateTime!
187
+ "End date for the query (required)"
188
+ endDate: DateTime!
189
+ "Maximum number of results (default: 100, max: 10000)"
190
+ limit: Int! = 100
191
+ where: AdHawkDevicePlayStatsFilterInput @cost(weight: "10")
192
+ order: [AdHawkDevicePlayStatsSortInput!] @cost(weight: "10")
193
+ ): [AdHawkDevicePlayStats] @cost(weight: "10")
194
+ """
195
+ Get device and media combined play statistics - shows what content played on which devices.
196
+ Useful for DooH reporting to analyze device/content performance matrix.
197
+ Example: Find which devices played a specific ad campaign most frequently.
198
+ """
199
+ deviceMediaPlayStats(
200
+ "Optional list of device IDs to filter by"
201
+ deviceId: [String!]
202
+ "Optional list of file IDs to filter by"
203
+ fileId: [String!]
204
+ "Start date for the query (required)"
205
+ startDate: DateTime!
206
+ "End date for the query (required)"
207
+ endDate: DateTime!
208
+ "Maximum number of results (default: 100, max: 10000)"
209
+ limit: Int! = 100
210
+ where: AdHawkDeviceMediaPlayStatsFilterInput @cost(weight: "10")
211
+ order: [AdHawkDeviceMediaPlayStatsSortInput!] @cost(weight: "10")
212
+ ): [AdHawkDeviceMediaPlayStats] @cost(weight: "10")
213
+ """
214
+ Get time-series play statistics - aggregated play data by time intervals.
215
+ Useful for DooH reporting to analyze playback trends over time (hourly, daily, weekly, etc.).
216
+ Example: Chart daily play counts for a specific media file over the past month.
217
+ """
218
+ playStatsByTime(
219
+ "Optional list of device IDs to filter by"
220
+ deviceId: [String!]
221
+ "Optional list of file IDs to filter by"
222
+ fileId: [String!]
223
+ "Time interval for aggregation (minute, hour, day, week, month)"
224
+ interval: AdHawkIntervalType! = DAY
225
+ "Group results by device (default: false)"
226
+ groupByDevice: Boolean! = false
227
+ "Group results by file (default: false)"
228
+ groupByFile: Boolean! = false
229
+ "Start date for the query (required)"
230
+ startDate: DateTime!
231
+ "End date for the query (required)"
232
+ endDate: DateTime!
233
+ "Maximum number of results (default: 1000, max: 10000)"
234
+ limit: Int! = 1000
235
+ where: AdHawkPlayStatsByTimeFilterInput @cost(weight: "10")
236
+ order: [AdHawkPlayStatsByTimeSortInput!] @cost(weight: "10")
237
+ ): [AdHawkPlayStatsByTime] @cost(weight: "10")
238
+ """
239
+ Get event flow data for Sankey-type visualizations.
240
+ Builds a chronological sequence of events indicating the path users took through sessions.
241
+ Useful for analyzing user navigation patterns and behavior flows.
242
+ """
243
+ eventFlow(
244
+ "Optional list of device IDs to filter by"
245
+ deviceId: [String!]
246
+ "Optional list of event names to filter by"
247
+ eventName: [String!]
248
+ "Maximum depth level for event flow (default: 6). Controls how many event transitions to include."
249
+ eventDepthLevel: Int! = 6
250
+ "Start date for the query (required)"
251
+ startDate: DateTime!
252
+ "End date for the query (required)"
253
+ endDate: DateTime!
254
+ "Maximum number of results (default: 1000, max: 10000)"
255
+ limit: Int! = 1000
256
+ where: AdHawkEventFlowFilterInput @cost(weight: "10")
257
+ order: [AdHawkEventFlowSortInput!] @cost(weight: "10")
258
+ ): [AdHawkEventFlow] @cost(weight: "10")
259
+ """
260
+ Get geographic heatmap data aggregated by location.
261
+ Groups impression data by geographic region returning a dataset aggregated by location.
262
+ Useful for heatmap or geographic visualizations.
263
+ """
264
+ heatMapData(
265
+ "Optional list of device IDs to filter by"
266
+ deviceId: [String!]
267
+ "Time interval for aggregation (minute, hour, day, week, month)"
268
+ interval: AdHawkIntervalType! = DAY
269
+ "Start date for the query (required)"
270
+ startDate: DateTime!
271
+ "End date for the query (required)"
272
+ endDate: DateTime!
273
+ "Maximum number of results (default: 1000, max: 10000)"
274
+ limit: Int! = 1000
275
+ where: AdHawkHeatMapDataFilterInput @cost(weight: "10")
276
+ order: [AdHawkHeatMapDataSortInput!] @cost(weight: "10")
277
+ ): [AdHawkHeatMapData] @cost(weight: "10")
278
+ """
279
+ Get geographic heatmap data for events aggregated by location.
280
+ Groups event data by geographic region returning a dataset aggregated by location.
281
+ Useful for heatmap or geographic visualizations of event activity.
282
+ """
283
+ eventHeatMapData(
284
+ "Optional list of device IDs to filter by"
285
+ deviceId: [String!]
286
+ "Optional list of event names to filter by"
287
+ eventName: [String!]
288
+ "Time interval for aggregation (minute, hour, day, week, month)"
289
+ interval: AdHawkIntervalType! = DAY
290
+ "Start date for the query (required)"
291
+ startDate: DateTime!
292
+ "End date for the query (required)"
293
+ endDate: DateTime!
294
+ "Maximum number of results (default: 1000, max: 10000)"
295
+ limit: Int! = 1000
296
+ where: AdHawkEventHeatMapDataFilterInput @cost(weight: "10")
297
+ order: [AdHawkEventHeatMapDataSortInput!] @cost(weight: "10")
298
+ ): [AdHawkEventHeatMapData] @cost(weight: "10")
299
+ """
300
+ Get media impressions (OTS - Opportunity To See) data aggregated by media file.
301
+ Joins audience/impression data with play logs to determine which audience members
302
+ had an opportunity to see specific media content during playback.
303
+ Useful for measuring media effectiveness and audience engagement.
304
+ """
305
+ mediaImpressions(
306
+ "Optional list of device IDs to filter by"
307
+ deviceId: [String!]
308
+ "Optional list of file/media IDs to filter by"
309
+ fileId: [String!]
310
+ "Minimum dwell time in milliseconds to count as \"viewed\" (default: 100ms)"
311
+ minDwellThreshold: Long! = 100
312
+ "Start date for the query (required)"
313
+ startDate: DateTime!
314
+ "End date for the query (required)"
315
+ endDate: DateTime!
316
+ "Maximum number of results (default: 100, max: 10000)"
317
+ limit: Int! = 100
318
+ where: AdHawkMediaImpressionsFilterInput @cost(weight: "10")
319
+ order: [AdHawkMediaImpressionsSortInput!] @cost(weight: "10")
320
+ ): [AdHawkMediaImpressions] @cost(weight: "10")
321
+ """
322
+ Get media impressions (OTS - Opportunity To See) data aggregated by device.
323
+ Joins audience/impression data with play logs to determine which devices
324
+ had the most audience engagement during media playback.
325
+ Useful for identifying high-performing locations and devices.
326
+ """
327
+ deviceMediaImpressions(
328
+ "Optional list of device IDs to filter by"
329
+ deviceId: [String!]
330
+ "Optional list of file/media IDs to filter by"
331
+ fileId: [String!]
332
+ "Minimum dwell time in milliseconds to count as \"viewed\" (default: 100ms)"
333
+ minDwellThreshold: Long! = 100
334
+ "Start date for the query (required)"
335
+ startDate: DateTime!
336
+ "End date for the query (required)"
337
+ endDate: DateTime!
338
+ "Maximum number of results (default: 100, max: 10000)"
339
+ limit: Int! = 100
340
+ where: AdHawkDeviceMediaImpressionsFilterInput @cost(weight: "10")
341
+ order: [AdHawkDeviceMediaImpressionsSortInput!] @cost(weight: "10")
342
+ ): [AdHawkDeviceMediaImpressions] @cost(weight: "10")
343
+ """
344
+ Gets alerts for the authenticated account.
345
+
346
+
347
+ **Returns:**
348
+ List of alerts
349
+ """
350
+ alert(
351
+ "Filter by specific alert IDs (encrypted)"
352
+ id: [String!]
353
+ "Filter by device IDs (encrypted)"
354
+ deviceId: [String!]
355
+ "Filter to show only active alerts"
356
+ activeOnly: Boolean
357
+ "Filter by resolved state"
358
+ resolved: Boolean
359
+ "Filter by organization ID (encrypted)"
360
+ orgId: String
361
+ "Maximum number of items to return"
362
+ limit: Int
363
+ where: AlertFilterInput @cost(weight: "10")
364
+ order: [AlertSortInput!] @cost(weight: "10")
365
+ ): [Alert] @cost(weight: "10")
366
+ """
367
+ Gets audit events for the authenticated account.
368
+ Requires the user to be an account owner.
369
+
370
+
371
+ **Returns:**
372
+ List of audit events
373
+ """
374
+ auditEvent(
375
+ "Filter by user ID (encrypted)"
376
+ userId: String
377
+ "Filter by event type"
378
+ eventType: String
379
+ "Filter by HTTP method (GET, POST, PUT, DELETE, etc.)"
380
+ httpMethod: String
381
+ "Filter by controller name"
382
+ controllerName: String
383
+ "Filter by action name"
384
+ actionName: String
385
+ "Filter events after this date"
386
+ startDate: DateTime
387
+ "Filter events before this date"
388
+ endDate: DateTime
389
+ "Filter by IP address"
390
+ ipAddress: String
391
+ "Filter by HTTP response code"
392
+ responseCode: String
393
+ "Maximum number of items to return"
394
+ limit: Int
395
+ where: AuditEventFilterInput @cost(weight: "10")
396
+ order: [AuditEventSortInput!] @cost(weight: "10")
397
+ ): [AuditEvent!]! @cost(weight: "10")
398
+ "Lists data tables in the account, with optional group filtering."
399
+ dataTables(
400
+ "Optional group ID to filter by"
401
+ groupId: String
402
+ "Number of tables per page (default 50)"
403
+ pageSize: Int! = 50
404
+ "Token for fetching the next page"
405
+ continuationToken: String
406
+ ): DataTableListResponse @cost(weight: "10")
407
+ "Gets a single data table definition by ID, including column schema."
408
+ dataTable("The data table ID" tableId: String): DataTableDetail
409
+ @cost(weight: "10")
410
+ "Lists rows in a data table, with optional filtering, sorting, and field selection."
411
+ dataTableRows(
412
+ "The data table ID"
413
+ tableId: String
414
+ """
415
+ Optional row filter as a JSON object encoded as a string. All conditions are
416
+ AND-ed together at the top level. Use the special key `$or` to express
417
+ disjunction.
418
+
419
+ Two shapes are accepted per column:
420
+
421
+ 1. Equality shortcut (string/number/boolean literal):
422
+ {"status": "active"} // equivalent to {"status": {"op":"eq","value":"active"}}
423
+
424
+ 2. Operator object form:
425
+ {"<columnKey>": {"op": "<operator>", ...args}}
426
+
427
+ Supported operators
428
+ -------------------
429
+ Value operators (require `value`):
430
+ eq equal
431
+ neq not equal
432
+ contains substring match (string columns)
433
+ notContains substring non-match
434
+ gt, gte greater than / greater or equal (number, date)
435
+ lt, lte less than / less or equal (number, date)
436
+
437
+ Range operators (require `from` and `to`):
438
+ inRange value is between from and to (inclusive)
439
+ outOfRange value is outside [from, to]
440
+
441
+ No-value operators (no `value` / `from` / `to`):
442
+ isEmpty column is null / empty string
443
+ isNotEmpty column has a value
444
+ positive number > 0
445
+ negative number < 0
446
+ beforeNow date < now (UTC)
447
+ afterNow date > now (UTC)
448
+ isToday date is on the current UTC calendar day
449
+
450
+ Composition
451
+ -----------
452
+ Use `$or` at the top level for disjunction. Each element is a normal filter
453
+ object whose own conditions are AND-ed:
454
+
455
+ {
456
+ "$or": [
457
+ { "category": "Entree" },
458
+ { "price": { "op": "lt", "value": 10 } }
459
+ ]
460
+ }
461
+
462
+ Examples
463
+ --------
464
+ {"active": true}
465
+ {"price": {"op": "gte", "value": 25}}
466
+ {"name": {"op": "contains", "value": "pizza"}}
467
+ {"score": {"op": "inRange", "from": 0, "to": 100}}
468
+ {"deletedAt": {"op": "isEmpty"}}
469
+ {"publishAt": {"op": "beforeNow"}}
470
+
471
+ Validation errors
472
+ -----------------
473
+ Invalid JSON, unknown operators, or missing required arguments produce a
474
+ GraphQL error with `extensions.code = "BAD_REQUEST"` and no stack trace.
475
+ """
476
+ filter: String
477
+ "Column key to sort by"
478
+ sort: String
479
+ "Sort direction: \"asc\" or \"desc\""
480
+ sortDir: String = "asc"
481
+ "Number of rows per page (default 50)"
482
+ pageSize: Int! = 50
483
+ "Token for fetching the next page"
484
+ continuationToken: String
485
+ "Comma-separated list of column keys to return"
486
+ fields: String
487
+ ): RowListResponse @cost(weight: "10")
488
+ "Gets a single row by ID."
489
+ dataTableRow("The data table ID" tableId: String, "The row ID" rowId: String): DataTableRowModel
490
+ @cost(weight: "10")
491
+ "Exports all rows from a data table as a CSV string."
492
+ exportDataTableRows("The data table ID" tableId: String): String
493
+ @cost(weight: "10")
494
+ "Lists version history for a row (newest first)."
495
+ dataTableRowVersions(
496
+ "The data table ID"
497
+ tableId: String
498
+ "The row ID"
499
+ rowId: String
500
+ "Number of versions per page (default 25)"
501
+ pageSize: Int! = 25
502
+ "Token for fetching the next page"
503
+ continuationToken: String
504
+ ): VersionListResponse @cost(weight: "10")
505
+ "Gets a specific version snapshot of a row."
506
+ dataTableRowVersion(
507
+ "The data table ID"
508
+ tableId: String
509
+ "The row ID"
510
+ rowId: String
511
+ "The version number to retrieve"
512
+ version: Int!
513
+ ): RowVersionModel @cost(weight: "10")
514
+ device(
515
+ id: [String!]
516
+ groupId: [String!]
517
+ groupName: [String!]
518
+ deviceTypeId: [String!]
519
+ includeSnap: Boolean
520
+ orgId: String
521
+ tag: [String!]
522
+ limit: Int
523
+ where: DeviceFilterInput @cost(weight: "10")
524
+ order: [DeviceSortInput!] @cost(weight: "10")
525
+ ): [Device] @cost(weight: "10")
526
+ deviceGroups(
527
+ id: String
528
+ tree: Boolean
529
+ limit: Int
530
+ where: GroupFilterInput @cost(weight: "10")
531
+ order: [GroupSortInput!] @cost(weight: "10")
532
+ ): [Group] @cost(weight: "10")
533
+ """
534
+ Gets the display commands configured for the authenticated account.
535
+ These commands define the available actions that can be sent to devices
536
+ (e.g., via the sendDeviceCommand mutation).
537
+ """
538
+ displayCommands(
539
+ where: DisplayCommandFilterInput @cost(weight: "10")
540
+ order: [DisplayCommandSortInput!] @cost(weight: "10")
541
+ ): [DisplayCommand] @cost(weight: "10")
542
+ media(
543
+ id: [String!]
544
+ groupId: [String!]
545
+ groupName: [String!]
546
+ orgId: String
547
+ tag: [String!]
548
+ limit: Int
549
+ where: MediaFilterInput @cost(weight: "10")
550
+ order: [MediaSortInput!] @cost(weight: "10")
551
+ ): [Media] @cost(weight: "10")
552
+ mediaGroups(
553
+ id: String
554
+ tree: Boolean
555
+ limit: Int
556
+ where: GroupFilterInput @cost(weight: "10")
557
+ order: [GroupSortInput!] @cost(weight: "10")
558
+ ): [Group] @cost(weight: "10")
559
+ """
560
+ Get the permissions for the currently authenticated user or API key.
561
+ Returns per-resource view/edit/delete flags and lists of allowed/denied mutation tool names.
562
+ AI agents should call this query at the start of every session to determine which action tools are available.
563
+ """
564
+ permissions: PermissionsResult @cost(weight: "10")
565
+ playlist(
566
+ id: [String!]
567
+ groupId: [String!]
568
+ groupName: [String!]
569
+ orgId: String
570
+ tag: [String!]
571
+ limit: Int
572
+ where: PlaylistFilterInput @cost(weight: "10")
573
+ order: [PlaylistSortInput!] @cost(weight: "10")
574
+ ): [Playlist] @cost(weight: "10")
575
+ playlistGroups(
576
+ id: String
577
+ tree: Boolean
578
+ limit: Int
579
+ where: GroupFilterInput @cost(weight: "10")
580
+ order: [GroupSortInput!] @cost(weight: "10")
581
+ ): [Group] @cost(weight: "10")
582
+ schedule(
583
+ id: [String!]
584
+ groupId: [String!]
585
+ groupName: [String!]
586
+ deviceId: String
587
+ orgId: String
588
+ tag: [String!]
589
+ limit: Int
590
+ where: ScheduleFilterInput @cost(weight: "10")
591
+ order: [ScheduleSortInput!] @cost(weight: "10")
592
+ ): [Schedule] @cost(weight: "10")
593
+ scheduleGroups(
594
+ id: String
595
+ tree: Boolean
596
+ limit: Int
597
+ where: GroupFilterInput @cost(weight: "10")
598
+ order: [GroupSortInput!] @cost(weight: "10")
599
+ ): [Group] @cost(weight: "10")
600
+ template(
601
+ id: [String!]
602
+ groupId: [String!]
603
+ groupName: [String!]
604
+ orgId: String
605
+ tag: [String!]
606
+ limit: Int
607
+ where: TemplateFilterInput @cost(weight: "10")
608
+ order: [TemplateSortInput!] @cost(weight: "10")
609
+ ): [Template] @cost(weight: "10")
610
+ templateGroups(
611
+ id: String
612
+ tree: Boolean
613
+ limit: Int
614
+ where: GroupFilterInput @cost(weight: "10")
615
+ order: [GroupSortInput!] @cost(weight: "10")
616
+ ): [Group] @cost(weight: "10")
617
+ user(
618
+ id: [String!]
619
+ limit: Int
620
+ where: UserFilterInput @cost(weight: "10")
621
+ order: [UserSortInput!] @cost(weight: "10")
622
+ ): [User] @cost(weight: "10")
623
+ }
624
+
625
+ type Mutation {
626
+ """
627
+ Create a new data table with the specified column schema.
628
+ Example: Create a menu board table with columns for item name, price, description, and image.
629
+ """
630
+ createDataTable(input: CreateDataTableInput): DataTableMutationResult
631
+ @cost(weight: "10")
632
+ """
633
+ Update an existing data table definition. Only provided fields are changed.
634
+ Example: Add a new "calories" column to a menu board table.
635
+ """
636
+ updateDataTable(input: UpdateDataTableInput): DataTableMutationResult
637
+ @cost(weight: "10")
638
+ "Delete a data table and all its rows."
639
+ deleteDataTable(tableId: String): DeleteResult @cost(weight: "10")
640
+ """
641
+ Create a new row in a data table.
642
+ Example: Add a new menu item to a menu board table.
643
+ """
644
+ createDataTableRow(input: CreateDataTableRowInput): DataTableRowMutationResult
645
+ @cost(weight: "10")
646
+ """
647
+ Update an existing row in a data table (partial update — only provided keys are changed).
648
+ Example: Update the price of a menu item.
649
+ """
650
+ updateDataTableRow(input: UpdateDataTableRowInput): DataTableRowMutationResult
651
+ @cost(weight: "10")
652
+ "Delete a row from a data table."
653
+ deleteDataTableRow(tableId: String, rowId: String): DeleteResult
654
+ @cost(weight: "10")
655
+ """
656
+ Batch create multiple rows in a data table (max 100 rows per call).
657
+ Example: Bulk-load menu items into a table from an external data source.
658
+ """
659
+ batchCreateDataTableRows(input: BatchCreateDataTableRowsInput): BatchCreateDataTableRowsResult
660
+ @cost(weight: "10")
661
+ "Batch delete multiple rows from a data table (max 100 row IDs per call)."
662
+ batchDeleteDataTableRows(input: BatchDeleteDataTableRowsInput): BatchDeleteDataTableRowsResult
663
+ @cost(weight: "10")
664
+ """
665
+ Import rows from CSV content into a data table.
666
+ Example: Import a spreadsheet of menu items. Use replace mode to overwrite all existing rows.
667
+ """
668
+ importDataTableRows(input: ImportDataTableRowsInput): ImportDataTableRowsResult
669
+ @cost(weight: "10")
670
+ "Reorder rows in a data table by specifying the desired row ID sequence."
671
+ reorderDataTableRows(input: ReorderDataTableRowsInput): DeleteResult
672
+ @cost(weight: "10")
673
+ """
674
+ Roll back a row to a previous version, creating a new version for the rollback action.
675
+ Example: Undo an accidental price change by restoring a previous version.
676
+ """
677
+ rollbackDataTableRow(input: RollbackDataTableRowInput): RollbackDataTableRowResult
678
+ @cost(weight: "10")
679
+ """
680
+ Send commands to a specific device.
681
+ Commands are dispatched via Azure SignalR, FCM, Pusher, and legacy SignalR channels
682
+ depending on the device type.
683
+
684
+ Known commands: restart, reboot, screenshot, refresh, display_on, display_off, volume (arg: 0-100), clear_cache, update.
685
+ """
686
+ sendDeviceCommand(deviceId: String, commands: [CommandInput]): CommandResult
687
+ @cost(weight: "10")
688
+ """
689
+ Send commands to multiple devices at once.
690
+
691
+ Known commands: restart, reboot, screenshot, refresh, display_on, display_off, volume (arg: 0-100), clear_cache, update.
692
+ """
693
+ sendBulkDeviceCommands(input: BulkCommandInput): BulkCommandResult
694
+ @cost(weight: "10")
695
+ """
696
+ Create a new media asset by downloading from a URL.
697
+ Useful for AI agents that generate images/videos and need to add them to the CMS.
698
+ Example: AI generates a promotional image via DALL-E and uploads it for digital signage display.
699
+ """
700
+ createMediaFromUrl(input: CreateMediaFromUrlInput): CreateMediaResult
701
+ @cost(weight: "10")
702
+ """
703
+ Update media metadata. Does not replace the media file itself.
704
+ Example: Set an end date on underperforming media to automatically stop playback.
705
+ """
706
+ updateMedia(input: UpdateMediaInput): UpdateMediaResult @cost(weight: "10")
707
+ """
708
+ Approve a media asset so it becomes eligible for playback. Reversible — a
709
+ subsequent DeclineMedia call will move the file back to declined state.
710
+ Example: AI agent automatically approves uploads that pass content moderation.
711
+ """
712
+ approveMedia(input: ApproveMediaInput): UpdateMediaResult @cost(weight: "10")
713
+ """
714
+ Decline a media asset so it is excluded from playback. Reversible — a
715
+ subsequent ApproveMedia call will move the file back to approved state.
716
+ Example: AI agent rejects uploads that fail content moderation, with a recorded reason.
717
+ """
718
+ declineMedia(input: DeclineMediaInput): UpdateMediaResult @cost(weight: "10")
719
+ """
720
+ Delete a media asset by ID.
721
+ Example: Remove AI-generated content that is no longer needed.
722
+
723
+ TEMPORARY: Short-circuited as a no-op until validated in production.
724
+ TODO: Re-enable actual deletion once testing is complete.
725
+ """
726
+ deleteMedia(id: String): DeleteResult @cost(weight: "10")
727
+ """
728
+ Add a content source to an existing playlist.
729
+ Example: AI generates a new image and adds it to the lobby playlist to improve engagement.
730
+ """
731
+ addPlaylistSource(input: AddPlaylistSourceInput): PlaylistMutationResult
732
+ @cost(weight: "10")
733
+ """
734
+ Update a source within a playlist.
735
+ Example: Change the duration of an ad slot based on engagement metrics.
736
+ """
737
+ updatePlaylistSource(input: UpdatePlaylistSourceInput): PlaylistMutationResult
738
+ @cost(weight: "10")
739
+ """
740
+ Remove a source from a playlist by source ID.
741
+ Example: Remove under-performing media from a playlist to improve overall engagement.
742
+ """
743
+ removePlaylistSource(playlistId: String, sourceId: String): PlaylistMutationResult
744
+ @cost(weight: "10")
745
+ """
746
+ Reorder sources within a playlist.
747
+ Example: Promote high-performing content to play first based on analytics data.
748
+ """
749
+ reorderPlaylistSources(input: ReorderPlaylistSourcesInput): PlaylistMutationResult
750
+ @cost(weight: "10")
751
+ }
752
+
6
753
  "Aggregated audience metrics for a device over a time period"
7
754
  type AdHawkAudienceMetrics {
8
755
  "The device ID"
@@ -43,7 +790,7 @@ type AdHawkAudienceMetrics {
43
790
  ageOver74: Long!
44
791
  "Number of motion sensor detections"
45
792
  motionCount: Long!
46
- "Number of audience\/face detections"
793
+ "Number of audience/face detections"
47
794
  audienceCount: Long!
48
795
  "Number of BLE beacon detections"
49
796
  bleCount: Long!
@@ -92,13 +839,13 @@ type AdHawkDeviceMediaPlayStats {
92
839
  fileName: String
93
840
  "Total number of times this media was played on this device"
94
841
  totalPlays: Long!
95
- "Total duration of all plays in milliseconds"
842
+ "Total duration of all plays in seconds"
96
843
  totalDuration: Long!
97
- "Average play duration in milliseconds"
844
+ "Average play duration in seconds"
98
845
  avgDuration: Decimal
99
- "First play timestamp for this device\/media combination"
846
+ "First play timestamp for this device/media combination"
100
847
  firstPlay: DateTime
101
- "Last play timestamp for this device\/media combination"
848
+ "Last play timestamp for this device/media combination"
102
849
  lastPlay: DateTime
103
850
  }
104
851
 
@@ -145,9 +892,9 @@ type AdHawkDevicePlayStats {
145
892
  deviceName: String
146
893
  "Total number of media files played on this device"
147
894
  totalPlays: Long!
148
- "Total duration of all plays in milliseconds"
895
+ "Total duration of all plays in seconds"
149
896
  totalDuration: Long!
150
- "Average play duration in milliseconds"
897
+ "Average play duration in seconds"
151
898
  avgDuration: Decimal
152
899
  "Number of unique media files played on this device"
153
900
  fileCount: Long!
@@ -208,7 +955,7 @@ type AdHawkEventLog {
208
955
  "Name of the event (e.g., \"button_click\", \"page_view\")"
209
956
  eventName: String
210
957
  "Additional properties associated with the event as key-value pairs"
211
- properties: [KeyValuePairOfStringAndObject!]
958
+ properties: [KeyValuePairOfNullableStringAndNullableObject!]
212
959
  "UTC offset of the device at the time of the event"
213
960
  utcOffset: Int
214
961
  }
@@ -256,11 +1003,11 @@ type AdHawkHeatMapData {
256
1003
  wifiCount: Long!
257
1004
  "Count of motion sensor impressions"
258
1005
  motionCount: Long!
259
- "Count of audience\/face detection impressions"
1006
+ "Count of audience/face detection impressions"
260
1007
  audienceCount: Long!
261
1008
  }
262
1009
 
263
- "Represents an audience impression\/detection entry"
1010
+ "Represents an audience impression/detection entry"
264
1011
  type AdHawkImpression {
265
1012
  "Unique identifier for this impression entry"
266
1013
  id: String
@@ -288,7 +1035,7 @@ type AdHawkImpression {
288
1035
  age: Int
289
1036
  "Age range classification"
290
1037
  ageRange: AdHawkAgeRange
291
- "Received Signal Strength Indicator for BLE\/WiFi detections"
1038
+ "Received Signal Strength Indicator for BLE/WiFi detections"
292
1039
  rssi: Int
293
1040
  "UTC offset of the device at the time of detection"
294
1041
  utcOffset: Int
@@ -300,9 +1047,9 @@ Joins audience/impression data with media play logs to determine which audience
300
1047
  members had an opportunity to see specific media content.
301
1048
  """
302
1049
  type AdHawkMediaImpressions {
303
- "The file\/media ID"
1050
+ "The file/media ID"
304
1051
  fileId: String
305
- "The file\/media name"
1052
+ "The file/media name"
306
1053
  fileName: String
307
1054
  "Total number of impressions that occurred during media playback"
308
1055
  totalImpressions: Long!
@@ -334,15 +1081,15 @@ type AdHawkMediaPlayStats {
334
1081
  fileName: String
335
1082
  "Total number of times this media was played"
336
1083
  totalPlays: Long!
337
- "Total duration of all plays in milliseconds"
1084
+ "Total duration of all plays in seconds"
338
1085
  totalDuration: Long!
339
- "Average play duration in milliseconds"
1086
+ "Average play duration in seconds"
340
1087
  avgDuration: Decimal
341
1088
  "Number of unique devices that played this media"
342
1089
  deviceCount: Long!
343
1090
  }
344
1091
 
345
- "Represents a device ping\/heartbeat log entry - records device health and status"
1092
+ "Represents a device ping/heartbeat log entry - records device health and status"
346
1093
  type AdHawkPingLog {
347
1094
  "Unique identifier for this ping log entry"
348
1095
  id: String
@@ -386,7 +1133,7 @@ type AdHawkPlayLog {
386
1133
  fileId: String
387
1134
  "The name of the media file"
388
1135
  fileName: String
389
- "Duration of the play in milliseconds"
1136
+ "Duration of the play in seconds"
390
1137
  duration: Int
391
1138
  "Type of play (internal use)"
392
1139
  type: Int
@@ -413,9 +1160,9 @@ type AdHawkPlayStatsByTime {
413
1160
  periodEnd: DateTime!
414
1161
  "Total number of plays during this period"
415
1162
  totalPlays: Long!
416
- "Total duration of all plays in milliseconds"
1163
+ "Total duration of all plays in seconds"
417
1164
  totalDuration: Long!
418
- "Average play duration in milliseconds"
1165
+ "Average play duration in seconds"
419
1166
  avgDuration: Decimal
420
1167
  "Number of unique devices (if aggregated by file)"
421
1168
  deviceCount: Long
@@ -661,7 +1408,7 @@ type DataTableColumnModel {
661
1408
  sortable: Boolean!
662
1409
  locked: Boolean!
663
1410
  options: [String]
664
- default: JSON
1411
+ default: Any
665
1412
  }
666
1413
 
667
1414
  type DataTableDetail {
@@ -694,8 +1441,20 @@ type DataTableMutationResult {
694
1441
  type DataTableRowModel {
695
1442
  id: String
696
1443
  sortOrder: Int!
697
- data: JSON
1444
+ """
1445
+ Stored row data as a JSON object keyed by column `key`. Values follow each
1446
+ column's `ColumnType` rules: STRING/RICHTEXT/HIDDEN/SELECT/URL/DATE/TIME are
1447
+ JSON strings, NUMBER is a JSON number, BOOLEAN is JSON true/false, and MEDIA is
1448
+ always a normalized object `{ url, thumbnailUrl, name, mimeType, mediaId? }`
1449
+ (id and id-object input forms are expanded server-side at write time).
1450
+ """
1451
+ data: Any
698
1452
  updatedAt: DateTime!
1453
+ """
1454
+ Optimistic concurrency token. Pass this value back as `eTag` in
1455
+ `updateDataTableRow` to ensure the row hasn't been changed since you read it.
1456
+ """
1457
+ eTag: String
699
1458
  }
700
1459
 
701
1460
  "Result from a data table row create or update mutation."
@@ -706,8 +1465,17 @@ type DataTableRowMutationResult {
706
1465
  row: DataTableRowModel
707
1466
  "Error message if the operation failed."
708
1467
  error: String
709
- "Validation errors if the row data failed schema validation."
1468
+ """
1469
+ Validation errors if the row data failed schema validation.
1470
+ Deprecated string-array form retained for backwards compatibility — new
1471
+ integrations should use StructuredValidationErrors.
1472
+ """
710
1473
  validationErrors: [String]
1474
+ """
1475
+ Structured validation errors with machine-readable codes, suitable for
1476
+ programmatic retry logic. Always populated when validation fails.
1477
+ """
1478
+ structuredValidationErrors: [ValidationError]
711
1479
  }
712
1480
 
713
1481
  type DataTableSummary {
@@ -755,9 +1523,9 @@ type Device {
755
1523
  languageCode: String
756
1524
  "The timestamp of the last content sync with the server"
757
1525
  lastUpdate: DateTime
758
- "The physical location\/address of the device"
1526
+ "The physical location/address of the device"
759
1527
  location: Location
760
- "The device ping\/heartbeat data"
1528
+ "The device ping/heartbeat data"
761
1529
  pingData: PingData
762
1530
  "The device registration key"
763
1531
  registrationKey: String
@@ -868,13 +1636,14 @@ type ImportRowErrorModel {
868
1636
  error: String
869
1637
  }
870
1638
 
871
- type KeyValuePairOfStringAndObject {
872
- key: String!
1639
+ type KeyValuePairOfNullableStringAndNullableObject {
1640
+ key: String
1641
+ value: Any
873
1642
  }
874
1643
 
875
- type KeyValuePairOfStringAndString {
876
- key: String!
877
- value: String!
1644
+ type KeyValuePairOfNullableStringAndNullableString {
1645
+ key: String
1646
+ value: String
878
1647
  }
879
1648
 
880
1649
  type Location {
@@ -925,6 +1694,14 @@ type Media {
925
1694
  width: Int
926
1695
  "The height of the media"
927
1696
  height: Int
1697
+ "Approval state. True = approved for playback, false = declined, null = pending review."
1698
+ isApproved: Boolean
1699
+ "Timestamp the media was approved, if applicable."
1700
+ approvedOn: DateTime
1701
+ "Timestamp the media was declined, if applicable."
1702
+ declinedOn: DateTime
1703
+ "Reason recorded when the media was declined, if any."
1704
+ declinedReason: String
928
1705
  "The media name"
929
1706
  name: String
930
1707
  "The group id"
@@ -966,105 +1743,6 @@ type Module {
966
1743
  sequence: Int
967
1744
  }
968
1745
 
969
- type Mutation @authorize {
970
- """
971
- Create a new data table with the specified column schema.
972
- Example: Create a menu board table with columns for item name, price, description, and image.
973
- """
974
- createDataTable(input: CreateDataTableInput): DataTableMutationResult @authorize(policy: "DataTables_Edit") @cost(weight: "10")
975
- """
976
- Update an existing data table definition. Only provided fields are changed.
977
- Example: Add a new "calories" column to a menu board table.
978
- """
979
- updateDataTable(input: UpdateDataTableInput): DataTableMutationResult @authorize(policy: "DataTables_Edit") @cost(weight: "10")
980
- "Delete a data table and all its rows."
981
- deleteDataTable(tableId: String): DeleteResult @authorize(policy: "DataTables_Delete") @cost(weight: "10")
982
- """
983
- Create a new row in a data table.
984
- Example: Add a new menu item to a menu board table.
985
- """
986
- createDataTableRow(input: CreateDataTableRowInput): DataTableRowMutationResult @authorize(policy: "DataTables_Edit") @cost(weight: "10")
987
- """
988
- Update an existing row in a data table (partial update — only provided keys are changed).
989
- Example: Update the price of a menu item.
990
- """
991
- updateDataTableRow(input: UpdateDataTableRowInput): DataTableRowMutationResult @authorize(policy: "DataTables_Edit") @cost(weight: "10")
992
- "Delete a row from a data table."
993
- deleteDataTableRow(tableId: String rowId: String): DeleteResult @authorize(policy: "DataTables_Delete") @cost(weight: "10")
994
- """
995
- Batch create multiple rows in a data table (max 100 rows per call).
996
- Example: Bulk-load menu items into a table from an external data source.
997
- """
998
- batchCreateDataTableRows(input: BatchCreateDataTableRowsInput): BatchCreateDataTableRowsResult @authorize(policy: "DataTables_Edit") @cost(weight: "10")
999
- "Batch delete multiple rows from a data table (max 100 row IDs per call)."
1000
- batchDeleteDataTableRows(input: BatchDeleteDataTableRowsInput): BatchDeleteDataTableRowsResult @authorize(policy: "DataTables_Delete") @cost(weight: "10")
1001
- """
1002
- Import rows from CSV content into a data table.
1003
- Example: Import a spreadsheet of menu items. Use replace mode to overwrite all existing rows.
1004
- """
1005
- importDataTableRows(input: ImportDataTableRowsInput): ImportDataTableRowsResult @authorize(policy: "DataTables_Edit") @cost(weight: "10")
1006
- "Reorder rows in a data table by specifying the desired row ID sequence."
1007
- reorderDataTableRows(input: ReorderDataTableRowsInput): DeleteResult @authorize(policy: "DataTables_Edit") @cost(weight: "10")
1008
- """
1009
- Roll back a row to a previous version, creating a new version for the rollback action.
1010
- Example: Undo an accidental price change by restoring a previous version.
1011
- """
1012
- rollbackDataTableRow(input: RollbackDataTableRowInput): RollbackDataTableRowResult @authorize(policy: "DataTables_Edit") @cost(weight: "10")
1013
- """
1014
- Send commands to a specific device.
1015
- Commands are dispatched via Azure SignalR, FCM, Pusher, and legacy SignalR channels
1016
- depending on the device type.
1017
-
1018
- Known commands: restart, reboot, screenshot, refresh, display_on, display_off, volume (arg: 0-100), clear_cache, update.
1019
- """
1020
- sendDeviceCommand(deviceId: String commands: [CommandInput]): CommandResult @authorize(policy: "Devices_Edit") @cost(weight: "10")
1021
- """
1022
- Send commands to multiple devices at once.
1023
-
1024
- Known commands: restart, reboot, screenshot, refresh, display_on, display_off, volume (arg: 0-100), clear_cache, update.
1025
- """
1026
- sendBulkDeviceCommands(input: BulkCommandInput): BulkCommandResult @authorize(policy: "Devices_Edit") @cost(weight: "10")
1027
- """
1028
- Create a new media asset by downloading from a URL.
1029
- Useful for AI agents that generate images/videos and need to add them to the CMS.
1030
- Example: AI generates a promotional image via DALL-E and uploads it for digital signage display.
1031
- """
1032
- createMediaFromUrl(input: CreateMediaFromUrlInput): CreateMediaResult @authorize(policy: "Files_Edit") @cost(weight: "10")
1033
- """
1034
- Update media metadata. Does not replace the media file itself.
1035
- Example: Set an end date on underperforming media to automatically stop playback.
1036
- """
1037
- updateMedia(input: UpdateMediaInput): UpdateMediaResult @authorize(policy: "Files_Edit") @cost(weight: "10")
1038
- """
1039
- Delete a media asset by ID.
1040
- Example: Remove AI-generated content that is no longer needed.
1041
-
1042
- TEMPORARY: Short-circuited as a no-op until validated in production.
1043
- TODO: Re-enable actual deletion once testing is complete.
1044
- """
1045
- deleteMedia(id: String): DeleteResult @authorize(policy: "Files_Delete") @cost(weight: "10")
1046
- """
1047
- Add a content source to an existing playlist.
1048
- Example: AI generates a new image and adds it to the lobby playlist to improve engagement.
1049
- """
1050
- addPlaylistSource(input: AddPlaylistSourceInput): PlaylistMutationResult @authorize(policy: "Playlists_Edit") @cost(weight: "10")
1051
- """
1052
- Update a source within a playlist.
1053
- Example: Change the duration of an ad slot based on engagement metrics.
1054
- """
1055
- updatePlaylistSource(input: UpdatePlaylistSourceInput): PlaylistMutationResult @authorize(policy: "Playlists_Edit") @cost(weight: "10")
1056
- """
1057
- Remove a source from a playlist by source ID.
1058
- Example: Remove under-performing media from a playlist to improve overall engagement.
1059
- """
1060
- removePlaylistSource(playlistId: String sourceId: String): PlaylistMutationResult @authorize(policy: "Playlists_Edit") @cost(weight: "10")
1061
- """
1062
- Reorder sources within a playlist.
1063
- Example: Promote high-performing content to play first based on analytics data.
1064
- """
1065
- reorderPlaylistSources(input: ReorderPlaylistSourcesInput): PlaylistMutationResult @authorize(policy: "Playlists_Edit") @cost(weight: "10")
1066
- }
1067
-
1068
1746
  """
1069
1747
  Result from the getPermissions query.
1070
1748
  Tells AI agents and MCP tools which operations are available for the current authenticated user or API key.
@@ -1090,7 +1768,7 @@ type PingData {
1090
1768
  "Ping type"
1091
1769
  type: String
1092
1770
  "Snapshot (screenshot) of live player content"
1093
- snap: [Byte!]
1771
+ snap: [UnsignedByte!]
1094
1772
  "Player version number"
1095
1773
  playerVersion: String
1096
1774
  "Player OS version"
@@ -1136,7 +1814,7 @@ type PingData {
1136
1814
  "Package download progress (percentage)"
1137
1815
  downloadPctComplete: Long
1138
1816
  "Dictionary of meta data"
1139
- meta: [KeyValuePairOfStringAndString!]
1817
+ meta: [KeyValuePairOfNullableStringAndNullableString!]
1140
1818
  "Current CPU temperature"
1141
1819
  cpuTemperature: Float
1142
1820
  }
@@ -1193,157 +1871,6 @@ type PlaylistMutationResult {
1193
1871
  error: String
1194
1872
  }
1195
1873
 
1196
- type Query @authorize {
1197
- """
1198
- Get play logs - records of when media content was played on devices.
1199
- Useful for tracking content playback history and calculating media impressions.
1200
- """
1201
- playLogs("Optional list of device IDs to filter by" deviceId: [String!] "Optional list of file IDs to filter by" fileId: [String!] "Start date for the query (required)" startDate: DateTime! "End date for the query (required)" endDate: DateTime! "Maximum number of results (default: 1000, max: 10000)" limit: Int! = 1000 where: AdHawkPlayLogFilterInput @cost(weight: "10") order: [AdHawkPlayLogSortInput!] @cost(weight: "10")): [AdHawkPlayLog] @authorize(policy: "AdHawk_View") @cost(weight: "10")
1202
- """
1203
- Get ping logs - device heartbeat/health data including CPU, memory, and disk usage.
1204
- Useful for monitoring device health and identifying performance issues.
1205
- Example: Find devices with average CPU usage over 90%.
1206
- """
1207
- pingLogs("Optional list of device IDs to filter by" deviceId: [String!] "Optional list of ping types to filter by (1=alive, 2=downloading, 4=playing)" type: [Int!] "Optional minimum CPU usage percentage to filter by" minCpuUsage: Float "Optional minimum memory usage percentage to filter by" minMemoryUsage: Float "Start date for the query (required)" startDate: DateTime! "End date for the query (required)" endDate: DateTime! "Maximum number of results (default: 1000, max: 10000)" limit: Int! = 1000 where: AdHawkPingLogFilterInput @cost(weight: "10") order: [AdHawkPingLogSortInput!] @cost(weight: "10")): [AdHawkPingLog] @authorize(policy: "AdHawk_View") @cost(weight: "10")
1208
- """
1209
- Get event logs - custom events generated by devices or applications.
1210
- Useful for tracking user interactions, button clicks, page views, etc.
1211
- """
1212
- eventLogs("Optional list of device IDs to filter by" deviceId: [String!] "Optional list of event names to filter by" eventName: [String!] "Optional session ID to filter by" sessionId: String "Start date for the query (required)" startDate: DateTime! "End date for the query (required)" endDate: DateTime! "Maximum number of results (default: 1000, max: 10000)" limit: Int! = 1000 where: AdHawkEventLogFilterInput @cost(weight: "10") order: [AdHawkEventLogSortInput!] @cost(weight: "10")): [AdHawkEventLog] @authorize(policy: "AdHawk_View") @cost(weight: "10")
1213
- """
1214
- Get aggregated event metrics for devices over a time period.
1215
- Useful for analyzing event patterns, user engagement, and interaction trends.
1216
- Metrics include total events, unique sessions, and event breakdowns.
1217
- """
1218
- eventMetrics("Optional list of device IDs to filter by" deviceId: [String!] "Optional list of event names to filter by" eventName: [String!] "Time interval for aggregation (minute, hour, day, week, month)" interval: AdHawkIntervalType! = DAY "Group results by device (default: true)" groupByDevice: Boolean! = false "Group results by event name (default: false)" groupByEvent: Boolean! = false "Start date for the query (required)" startDate: DateTime! "End date for the query (required)" endDate: DateTime! "Maximum number of results (default: 1000, max: 10000)" limit: Int! = 1000 where: AdHawkEventMetricsFilterInput @cost(weight: "10") order: [AdHawkEventMetricsSortInput!] @cost(weight: "10")): [AdHawkEventMetrics] @authorize(policy: "AdHawk_View") @cost(weight: "10")
1219
- """
1220
- Get impressions - audience detection data from sensors (motion, face detection, BLE, WiFi).
1221
- Useful for analyzing visitor demographics, dwell time, and traffic patterns.
1222
- """
1223
- impressions("Optional list of device IDs to filter by" deviceId: [String!] "Optional list of impression types to filter by (8=motion, 64=audience, 128=ble, 256=wifi)" type: [Int!] "Optional gender to filter by" gender: AdHawkGender "Optional minimum dwell time in milliseconds" minDwellTime: Long "Start date for the query (required)" startDate: DateTime! "End date for the query (required)" endDate: DateTime! "Maximum number of results (default: 1000, max: 10000)" limit: Int! = 1000 where: AdHawkImpressionFilterInput @cost(weight: "10") order: [AdHawkImpressionSortInput!] @cost(weight: "10")): [AdHawkImpression] @authorize(policy: "AdHawk_View") @cost(weight: "10")
1224
- """
1225
- Get aggregated device health metrics over a time period.
1226
- Useful for monitoring fleet health, identifying problematic devices, and capacity planning.
1227
- Metrics include CPU, memory, disk usage, and network traffic.
1228
- """
1229
- deviceMetrics("Optional list of device IDs to filter by" deviceId: [String!] "Time interval for aggregation (minute, hour, day, week, month)" interval: AdHawkIntervalType! = DAY "Start date for the query (required)" startDate: DateTime! "End date for the query (required)" endDate: DateTime! "Maximum number of results (default: 1000, max: 10000)" limit: Int! = 1000 where: AdHawkDeviceMetricsFilterInput @cost(weight: "10") order: [AdHawkDeviceMetricsSortInput!] @cost(weight: "10")): [AdHawkDeviceMetrics] @authorize(policy: "AdHawk_View") @cost(weight: "10")
1230
- """
1231
- Get aggregated audience metrics for devices over a time period.
1232
- Useful for analyzing visitor demographics, traffic patterns, and engagement.
1233
- Metrics include impressions, unique visitors, dwell time, gender, and age breakdowns.
1234
- """
1235
- audienceMetrics("Optional list of device IDs to filter by" deviceId: [String!] "Time interval for aggregation (minute, hour, day, week, month)" interval: AdHawkIntervalType! = DAY "When true, queries exit events with dwell time data. When false (default), queries enter events without dwell time." includeDwellTime: Boolean! = false "Start date for the query (required)" startDate: DateTime! "End date for the query (required)" endDate: DateTime! "Maximum number of results (default: 1000, max: 10000)" limit: Int! = 1000 where: AdHawkAudienceMetricsFilterInput @cost(weight: "10") order: [AdHawkAudienceMetricsSortInput!] @cost(weight: "10")): [AdHawkAudienceMetrics] @authorize(policy: "AdHawk_View") @cost(weight: "10")
1236
- """
1237
- Get media play statistics - aggregated play counts and durations for media files.
1238
- Useful for analyzing content performance and identifying popular media.
1239
- """
1240
- mediaPlayStats("Optional list of device IDs to filter by" deviceId: [String!] "Optional list of file IDs to filter by" fileId: [String!] "Start date for the query (required)" startDate: DateTime! "End date for the query (required)" endDate: DateTime! "Maximum number of results (default: 100, max: 10000)" limit: Int! = 100 where: AdHawkMediaPlayStatsFilterInput @cost(weight: "10") order: [AdHawkMediaPlayStatsSortInput!] @cost(weight: "10")): [AdHawkMediaPlayStats] @authorize(policy: "AdHawk_View") @cost(weight: "10")
1241
- """
1242
- Get device play statistics - aggregated play counts and duration for each device.
1243
- Useful for DooH reporting to analyze device performance and content distribution.
1244
- Example: Find which devices played the most content in a date range.
1245
- """
1246
- devicePlayStats("Optional list of device IDs to filter by" deviceId: [String!] "Optional list of file IDs to filter by" fileId: [String!] "Start date for the query (required)" startDate: DateTime! "End date for the query (required)" endDate: DateTime! "Maximum number of results (default: 100, max: 10000)" limit: Int! = 100 where: AdHawkDevicePlayStatsFilterInput @cost(weight: "10") order: [AdHawkDevicePlayStatsSortInput!] @cost(weight: "10")): [AdHawkDevicePlayStats] @authorize(policy: "AdHawk_View") @cost(weight: "10")
1247
- """
1248
- Get device and media combined play statistics - shows what content played on which devices.
1249
- Useful for DooH reporting to analyze device/content performance matrix.
1250
- Example: Find which devices played a specific ad campaign most frequently.
1251
- """
1252
- deviceMediaPlayStats("Optional list of device IDs to filter by" deviceId: [String!] "Optional list of file IDs to filter by" fileId: [String!] "Start date for the query (required)" startDate: DateTime! "End date for the query (required)" endDate: DateTime! "Maximum number of results (default: 100, max: 10000)" limit: Int! = 100 where: AdHawkDeviceMediaPlayStatsFilterInput @cost(weight: "10") order: [AdHawkDeviceMediaPlayStatsSortInput!] @cost(weight: "10")): [AdHawkDeviceMediaPlayStats] @authorize(policy: "AdHawk_View") @cost(weight: "10")
1253
- """
1254
- Get time-series play statistics - aggregated play data by time intervals.
1255
- Useful for DooH reporting to analyze playback trends over time (hourly, daily, weekly, etc.).
1256
- Example: Chart daily play counts for a specific media file over the past month.
1257
- """
1258
- playStatsByTime("Optional list of device IDs to filter by" deviceId: [String!] "Optional list of file IDs to filter by" fileId: [String!] "Time interval for aggregation (minute, hour, day, week, month)" interval: AdHawkIntervalType! = DAY "Group results by device (default: false)" groupByDevice: Boolean! = false "Group results by file (default: false)" groupByFile: Boolean! = false "Start date for the query (required)" startDate: DateTime! "End date for the query (required)" endDate: DateTime! "Maximum number of results (default: 1000, max: 10000)" limit: Int! = 1000 where: AdHawkPlayStatsByTimeFilterInput @cost(weight: "10") order: [AdHawkPlayStatsByTimeSortInput!] @cost(weight: "10")): [AdHawkPlayStatsByTime] @authorize(policy: "AdHawk_View") @cost(weight: "10")
1259
- """
1260
- Get event flow data for Sankey-type visualizations.
1261
- Builds a chronological sequence of events indicating the path users took through sessions.
1262
- Useful for analyzing user navigation patterns and behavior flows.
1263
- """
1264
- eventFlow("Optional list of device IDs to filter by" deviceId: [String!] "Optional list of event names to filter by" eventName: [String!] "Maximum depth level for event flow (default: 6). Controls how many event transitions to include." eventDepthLevel: Int! = 6 "Start date for the query (required)" startDate: DateTime! "End date for the query (required)" endDate: DateTime! "Maximum number of results (default: 1000, max: 10000)" limit: Int! = 1000 where: AdHawkEventFlowFilterInput @cost(weight: "10") order: [AdHawkEventFlowSortInput!] @cost(weight: "10")): [AdHawkEventFlow] @authorize(policy: "AdHawk_View") @cost(weight: "10")
1265
- """
1266
- Get geographic heatmap data aggregated by location.
1267
- Groups impression data by geographic region returning a dataset aggregated by location.
1268
- Useful for heatmap or geographic visualizations.
1269
- """
1270
- heatMapData("Optional list of device IDs to filter by" deviceId: [String!] "Time interval for aggregation (minute, hour, day, week, month)" interval: AdHawkIntervalType! = DAY "Start date for the query (required)" startDate: DateTime! "End date for the query (required)" endDate: DateTime! "Maximum number of results (default: 1000, max: 10000)" limit: Int! = 1000 where: AdHawkHeatMapDataFilterInput @cost(weight: "10") order: [AdHawkHeatMapDataSortInput!] @cost(weight: "10")): [AdHawkHeatMapData] @authorize(policy: "AdHawk_View") @cost(weight: "10")
1271
- """
1272
- Get geographic heatmap data for events aggregated by location.
1273
- Groups event data by geographic region returning a dataset aggregated by location.
1274
- Useful for heatmap or geographic visualizations of event activity.
1275
- """
1276
- eventHeatMapData("Optional list of device IDs to filter by" deviceId: [String!] "Optional list of event names to filter by" eventName: [String!] "Time interval for aggregation (minute, hour, day, week, month)" interval: AdHawkIntervalType! = DAY "Start date for the query (required)" startDate: DateTime! "End date for the query (required)" endDate: DateTime! "Maximum number of results (default: 1000, max: 10000)" limit: Int! = 1000 where: AdHawkEventHeatMapDataFilterInput @cost(weight: "10") order: [AdHawkEventHeatMapDataSortInput!] @cost(weight: "10")): [AdHawkEventHeatMapData] @authorize(policy: "AdHawk_View") @cost(weight: "10")
1277
- """
1278
- Get media impressions (OTS - Opportunity To See) data aggregated by media file.
1279
- Joins audience/impression data with play logs to determine which audience members
1280
- had an opportunity to see specific media content during playback.
1281
- Useful for measuring media effectiveness and audience engagement.
1282
- """
1283
- mediaImpressions("Optional list of device IDs to filter by" deviceId: [String!] "Optional list of file\/media IDs to filter by" fileId: [String!] "Minimum dwell time in milliseconds to count as \"viewed\" (default: 100ms)" minDwellThreshold: Long! = 100 "Start date for the query (required)" startDate: DateTime! "End date for the query (required)" endDate: DateTime! "Maximum number of results (default: 100, max: 10000)" limit: Int! = 100 where: AdHawkMediaImpressionsFilterInput @cost(weight: "10") order: [AdHawkMediaImpressionsSortInput!] @cost(weight: "10")): [AdHawkMediaImpressions] @authorize(policy: "AdHawk_View") @cost(weight: "10")
1284
- """
1285
- Get media impressions (OTS - Opportunity To See) data aggregated by device.
1286
- Joins audience/impression data with play logs to determine which devices
1287
- had the most audience engagement during media playback.
1288
- Useful for identifying high-performing locations and devices.
1289
- """
1290
- deviceMediaImpressions("Optional list of device IDs to filter by" deviceId: [String!] "Optional list of file\/media IDs to filter by" fileId: [String!] "Minimum dwell time in milliseconds to count as \"viewed\" (default: 100ms)" minDwellThreshold: Long! = 100 "Start date for the query (required)" startDate: DateTime! "End date for the query (required)" endDate: DateTime! "Maximum number of results (default: 100, max: 10000)" limit: Int! = 100 where: AdHawkDeviceMediaImpressionsFilterInput @cost(weight: "10") order: [AdHawkDeviceMediaImpressionsSortInput!] @cost(weight: "10")): [AdHawkDeviceMediaImpressions] @authorize(policy: "AdHawk_View") @cost(weight: "10")
1291
- """
1292
- Gets alerts for the authenticated account.
1293
-
1294
-
1295
- **Returns:**
1296
- List of alerts
1297
- """
1298
- alert("Filter by specific alert IDs (encrypted)" id: [String!] "Filter by device IDs (encrypted)" deviceId: [String!] "Filter to show only active alerts" activeOnly: Boolean "Filter by resolved state" resolved: Boolean "Filter by organization ID (encrypted)" orgId: String "Maximum number of items to return" limit: Int where: AlertFilterInput @cost(weight: "10") order: [AlertSortInput!] @cost(weight: "10")): [Alert] @authorize(policy: "Alerts_View") @cost(weight: "10")
1299
- """
1300
- Gets audit events for the authenticated account.
1301
- Requires the user to be an account owner.
1302
-
1303
-
1304
- **Returns:**
1305
- List of audit events
1306
- """
1307
- auditEvent("Filter by user ID (encrypted)" userId: String "Filter by event type" eventType: String "Filter by HTTP method (GET, POST, PUT, DELETE, etc.)" httpMethod: String "Filter by controller name" controllerName: String "Filter by action name" actionName: String "Filter events after this date" startDate: DateTime "Filter events before this date" endDate: DateTime "Filter by IP address" ipAddress: String "Filter by HTTP response code" responseCode: String "Maximum number of items to return" limit: Int where: AuditEventFilterInput @cost(weight: "10") order: [AuditEventSortInput!] @cost(weight: "10")): [AuditEvent!]! @authorize(policy: "AuditEventsOwnerOnly") @cost(weight: "10")
1308
- "Lists data tables in the account, with optional group filtering."
1309
- dataTables("Optional group ID to filter by" groupId: String "Number of tables per page (default 50)" pageSize: Int! = 50 "Token for fetching the next page" continuationToken: String): DataTableListResponse @authorize(policy: "DataTables_View") @cost(weight: "10")
1310
- "Gets a single data table definition by ID, including column schema."
1311
- dataTable("The data table ID" tableId: String): DataTableDetail @authorize(policy: "DataTables_View") @cost(weight: "10")
1312
- "Lists rows in a data table, with optional filtering, sorting, and field selection."
1313
- dataTableRows("The data table ID" tableId: String "Optional filter as a JSON string (e.g., {\"status\":\"active\"})" filter: String "Column key to sort by" sort: String "Sort direction: \"asc\" or \"desc\"" sortDir: String = "asc" "Number of rows per page (default 50)" pageSize: Int! = 50 "Token for fetching the next page" continuationToken: String "Comma-separated list of column keys to return" fields: String): RowListResponse @authorize(policy: "DataTables_View") @cost(weight: "10")
1314
- "Gets a single row by ID."
1315
- dataTableRow("The data table ID" tableId: String "The row ID" rowId: String): DataTableRowModel @authorize(policy: "DataTables_View") @cost(weight: "10")
1316
- "Exports all rows from a data table as a CSV string."
1317
- exportDataTableRows("The data table ID" tableId: String): String @authorize(policy: "DataTables_View") @cost(weight: "10")
1318
- "Lists version history for a row (newest first)."
1319
- dataTableRowVersions("The data table ID" tableId: String "The row ID" rowId: String "Number of versions per page (default 25)" pageSize: Int! = 25 "Token for fetching the next page" continuationToken: String): VersionListResponse @authorize(policy: "DataTables_View") @cost(weight: "10")
1320
- "Gets a specific version snapshot of a row."
1321
- dataTableRowVersion("The data table ID" tableId: String "The row ID" rowId: String "The version number to retrieve" version: Int!): RowVersionModel @authorize(policy: "DataTables_View") @cost(weight: "10")
1322
- device(id: [String!] groupId: [String!] groupName: [String!] deviceTypeId: [String!] includeSnap: Boolean orgId: String tag: [String!] limit: Int where: DeviceFilterInput @cost(weight: "10") order: [DeviceSortInput!] @cost(weight: "10")): [Device] @authorize(policy: "Devices_View") @cost(weight: "10")
1323
- deviceGroups(id: String tree: Boolean limit: Int where: GroupFilterInput @cost(weight: "10") order: [GroupSortInput!] @cost(weight: "10")): [Group] @authorize(policy: "Devices_View") @cost(weight: "10")
1324
- """
1325
- Gets the display commands configured for the authenticated account.
1326
- These commands define the available actions that can be sent to devices
1327
- (e.g., via the sendDeviceCommand mutation).
1328
- """
1329
- displayCommands(where: DisplayCommandFilterInput @cost(weight: "10") order: [DisplayCommandSortInput!] @cost(weight: "10")): [DisplayCommand] @authorize(policy: "Devices_View") @cost(weight: "10")
1330
- media(id: [String!] groupId: [String!] groupName: [String!] orgId: String tag: [String!] limit: Int where: MediaFilterInput @cost(weight: "10") order: [MediaSortInput!] @cost(weight: "10")): [Media] @authorize(policy: "Files_View") @cost(weight: "10")
1331
- mediaGroups(id: String tree: Boolean limit: Int where: GroupFilterInput @cost(weight: "10") order: [GroupSortInput!] @cost(weight: "10")): [Group] @authorize(policy: "Files_View") @cost(weight: "10")
1332
- """
1333
- Get the permissions for the currently authenticated user or API key.
1334
- Returns per-resource view/edit/delete flags and lists of allowed/denied mutation tool names.
1335
- AI agents should call this query at the start of every session to determine which action tools are available.
1336
- """
1337
- permissions: PermissionsResult @authorize @cost(weight: "10")
1338
- playlist(id: [String!] groupId: [String!] groupName: [String!] orgId: String tag: [String!] limit: Int where: PlaylistFilterInput @cost(weight: "10") order: [PlaylistSortInput!] @cost(weight: "10")): [Playlist] @authorize(policy: "Playlists_View") @cost(weight: "10")
1339
- playlistGroups(id: String tree: Boolean limit: Int where: GroupFilterInput @cost(weight: "10") order: [GroupSortInput!] @cost(weight: "10")): [Group] @authorize(policy: "Playlists_View") @cost(weight: "10")
1340
- schedule(id: [String!] groupId: [String!] groupName: [String!] deviceId: String orgId: String tag: [String!] limit: Int where: ScheduleFilterInput @cost(weight: "10") order: [ScheduleSortInput!] @cost(weight: "10")): [Schedule] @authorize(policy: "Schedules_View") @cost(weight: "10")
1341
- scheduleGroups(id: String tree: Boolean limit: Int where: GroupFilterInput @cost(weight: "10") order: [GroupSortInput!] @cost(weight: "10")): [Group] @authorize(policy: "Schedules_View") @cost(weight: "10")
1342
- template(id: [String!] groupId: [String!] groupName: [String!] orgId: String tag: [String!] limit: Int where: TemplateFilterInput @cost(weight: "10") order: [TemplateSortInput!] @cost(weight: "10")): [Template] @authorize(policy: "Templates_View") @cost(weight: "10")
1343
- templateGroups(id: String tree: Boolean limit: Int where: GroupFilterInput @cost(weight: "10") order: [GroupSortInput!] @cost(weight: "10")): [Group] @authorize(policy: "Templates_View") @cost(weight: "10")
1344
- user(id: [String!] limit: Int where: UserFilterInput @cost(weight: "10") order: [UserSortInput!] @cost(weight: "10")): [User] @authorize(policy: "Account_ManageUsers_View") @cost(weight: "10")
1345
- }
1346
-
1347
1874
  "Per-resource permission summary."
1348
1875
  type ResourcePermission {
1349
1876
  "The resource area (e.g., 'Devices', 'Files', 'Playlists', 'Schedules', 'Alerts', 'AdHawk')."
@@ -1379,9 +1906,9 @@ type RowVersionModel {
1379
1906
  rowId: String
1380
1907
  version: Int!
1381
1908
  action: String
1382
- data: JSON
1909
+ data: Any
1383
1910
  changedFields: [String]
1384
- previousValues: JSON
1911
+ previousValues: Any
1385
1912
  changedBy: String
1386
1913
  timestamp: DateTime!
1387
1914
  }
@@ -1614,12 +2141,35 @@ type User {
1614
2141
  isTwoFactor: Boolean
1615
2142
  }
1616
2143
 
2144
+ "Structured validation error suitable for programmatic handling and retry."
2145
+ type ValidationError {
2146
+ """
2147
+ The column key (matches `DataTableColumn.key`) that failed validation.
2148
+ May be null for table-level errors.
2149
+ """
2150
+ field: String
2151
+ "Machine-readable error code."
2152
+ code: ValidationErrorCode!
2153
+ "Human-readable error message describing the violation."
2154
+ message: String
2155
+ }
2156
+
1617
2157
  type VersionListResponse {
1618
2158
  data: [RowVersionModel]
1619
2159
  totalCount: Int!
1620
2160
  continuationToken: String
1621
2161
  }
1622
2162
 
2163
+ "Input for adding a content source to a playlist."
2164
+ input AddPlaylistSourceInput {
2165
+ "The playlist ID to add the source to."
2166
+ playlistId: String
2167
+ "The source to add."
2168
+ source: SourceInput
2169
+ "Optional position (0-based index). If omitted, appends to end."
2170
+ position: Int
2171
+ }
2172
+
1623
2173
  "Aggregated audience metrics for a device over a time period"
1624
2174
  input AdHawkAudienceMetricsFilterInput {
1625
2175
  and: [AdHawkAudienceMetricsFilterInput!]
@@ -1662,7 +2212,7 @@ input AdHawkAudienceMetricsFilterInput {
1662
2212
  ageOver74: LongOperationFilterInput
1663
2213
  "Number of motion sensor detections"
1664
2214
  motionCount: LongOperationFilterInput
1665
- "Number of audience\/face detections"
2215
+ "Number of audience/face detections"
1666
2216
  audienceCount: LongOperationFilterInput
1667
2217
  "Number of BLE beacon detections"
1668
2218
  bleCount: LongOperationFilterInput
@@ -1710,7 +2260,7 @@ input AdHawkAudienceMetricsSortInput {
1710
2260
  ageOver74: SortEnumType @cost(weight: "10")
1711
2261
  "Number of motion sensor detections"
1712
2262
  motionCount: SortEnumType @cost(weight: "10")
1713
- "Number of audience\/face detections"
2263
+ "Number of audience/face detections"
1714
2264
  audienceCount: SortEnumType @cost(weight: "10")
1715
2265
  "Number of BLE beacon detections"
1716
2266
  bleCount: SortEnumType @cost(weight: "10")
@@ -1789,13 +2339,13 @@ input AdHawkDeviceMediaPlayStatsFilterInput {
1789
2339
  fileName: StringOperationFilterInput
1790
2340
  "Total number of times this media was played on this device"
1791
2341
  totalPlays: LongOperationFilterInput
1792
- "Total duration of all plays in milliseconds"
2342
+ "Total duration of all plays in seconds"
1793
2343
  totalDuration: LongOperationFilterInput
1794
- "Average play duration in milliseconds"
2344
+ "Average play duration in seconds"
1795
2345
  avgDuration: DecimalOperationFilterInput
1796
- "First play timestamp for this device\/media combination"
2346
+ "First play timestamp for this device/media combination"
1797
2347
  firstPlay: DateTimeOperationFilterInput
1798
- "Last play timestamp for this device\/media combination"
2348
+ "Last play timestamp for this device/media combination"
1799
2349
  lastPlay: DateTimeOperationFilterInput
1800
2350
  }
1801
2351
 
@@ -1814,13 +2364,13 @@ input AdHawkDeviceMediaPlayStatsSortInput {
1814
2364
  fileName: SortEnumType @cost(weight: "10")
1815
2365
  "Total number of times this media was played on this device"
1816
2366
  totalPlays: SortEnumType @cost(weight: "10")
1817
- "Total duration of all plays in milliseconds"
2367
+ "Total duration of all plays in seconds"
1818
2368
  totalDuration: SortEnumType @cost(weight: "10")
1819
- "Average play duration in milliseconds"
2369
+ "Average play duration in seconds"
1820
2370
  avgDuration: SortEnumType @cost(weight: "10")
1821
- "First play timestamp for this device\/media combination"
2371
+ "First play timestamp for this device/media combination"
1822
2372
  firstPlay: SortEnumType @cost(weight: "10")
1823
- "Last play timestamp for this device\/media combination"
2373
+ "Last play timestamp for this device/media combination"
1824
2374
  lastPlay: SortEnumType @cost(weight: "10")
1825
2375
  }
1826
2376
 
@@ -1903,9 +2453,9 @@ input AdHawkDevicePlayStatsFilterInput {
1903
2453
  deviceName: StringOperationFilterInput
1904
2454
  "Total number of media files played on this device"
1905
2455
  totalPlays: LongOperationFilterInput
1906
- "Total duration of all plays in milliseconds"
2456
+ "Total duration of all plays in seconds"
1907
2457
  totalDuration: LongOperationFilterInput
1908
- "Average play duration in milliseconds"
2458
+ "Average play duration in seconds"
1909
2459
  avgDuration: DecimalOperationFilterInput
1910
2460
  "Number of unique media files played on this device"
1911
2461
  fileCount: LongOperationFilterInput
@@ -1926,9 +2476,9 @@ input AdHawkDevicePlayStatsSortInput {
1926
2476
  deviceName: SortEnumType @cost(weight: "10")
1927
2477
  "Total number of media files played on this device"
1928
2478
  totalPlays: SortEnumType @cost(weight: "10")
1929
- "Total duration of all plays in milliseconds"
2479
+ "Total duration of all plays in seconds"
1930
2480
  totalDuration: SortEnumType @cost(weight: "10")
1931
- "Average play duration in milliseconds"
2481
+ "Average play duration in seconds"
1932
2482
  avgDuration: SortEnumType @cost(weight: "10")
1933
2483
  "Number of unique media files played on this device"
1934
2484
  fileCount: SortEnumType @cost(weight: "10")
@@ -2123,7 +2673,7 @@ input AdHawkHeatMapDataFilterInput {
2123
2673
  wifiCount: LongOperationFilterInput
2124
2674
  "Count of motion sensor impressions"
2125
2675
  motionCount: LongOperationFilterInput
2126
- "Count of audience\/face detection impressions"
2676
+ "Count of audience/face detection impressions"
2127
2677
  audienceCount: LongOperationFilterInput
2128
2678
  }
2129
2679
 
@@ -2148,11 +2698,11 @@ input AdHawkHeatMapDataSortInput {
2148
2698
  wifiCount: SortEnumType @cost(weight: "10")
2149
2699
  "Count of motion sensor impressions"
2150
2700
  motionCount: SortEnumType @cost(weight: "10")
2151
- "Count of audience\/face detection impressions"
2701
+ "Count of audience/face detection impressions"
2152
2702
  audienceCount: SortEnumType @cost(weight: "10")
2153
2703
  }
2154
2704
 
2155
- "Represents an audience impression\/detection entry"
2705
+ "Represents an audience impression/detection entry"
2156
2706
  input AdHawkImpressionFilterInput {
2157
2707
  and: [AdHawkImpressionFilterInput!]
2158
2708
  or: [AdHawkImpressionFilterInput!]
@@ -2182,13 +2732,13 @@ input AdHawkImpressionFilterInput {
2182
2732
  age: IntOperationFilterInput
2183
2733
  "Age range classification"
2184
2734
  ageRange: NullableOfAdHawkAgeRangeOperationFilterInput
2185
- "Received Signal Strength Indicator for BLE\/WiFi detections"
2735
+ "Received Signal Strength Indicator for BLE/WiFi detections"
2186
2736
  rssi: IntOperationFilterInput
2187
2737
  "UTC offset of the device at the time of detection"
2188
2738
  utcOffset: IntOperationFilterInput
2189
2739
  }
2190
2740
 
2191
- "Represents an audience impression\/detection entry"
2741
+ "Represents an audience impression/detection entry"
2192
2742
  input AdHawkImpressionSortInput {
2193
2743
  "Unique identifier for this impression entry"
2194
2744
  id: SortEnumType @cost(weight: "10")
@@ -2216,7 +2766,7 @@ input AdHawkImpressionSortInput {
2216
2766
  age: SortEnumType @cost(weight: "10")
2217
2767
  "Age range classification"
2218
2768
  ageRange: SortEnumType @cost(weight: "10")
2219
- "Received Signal Strength Indicator for BLE\/WiFi detections"
2769
+ "Received Signal Strength Indicator for BLE/WiFi detections"
2220
2770
  rssi: SortEnumType @cost(weight: "10")
2221
2771
  "UTC offset of the device at the time of detection"
2222
2772
  utcOffset: SortEnumType @cost(weight: "10")
@@ -2230,9 +2780,9 @@ members had an opportunity to see specific media content.
2230
2780
  input AdHawkMediaImpressionsFilterInput {
2231
2781
  and: [AdHawkMediaImpressionsFilterInput!]
2232
2782
  or: [AdHawkMediaImpressionsFilterInput!]
2233
- "The file\/media ID"
2783
+ "The file/media ID"
2234
2784
  fileId: StringOperationFilterInput
2235
- "The file\/media name"
2785
+ "The file/media name"
2236
2786
  fileName: StringOperationFilterInput
2237
2787
  "Total number of impressions that occurred during media playback"
2238
2788
  totalImpressions: LongOperationFilterInput
@@ -2262,9 +2812,9 @@ Joins audience/impression data with media play logs to determine which audience
2262
2812
  members had an opportunity to see specific media content.
2263
2813
  """
2264
2814
  input AdHawkMediaImpressionsSortInput {
2265
- "The file\/media ID"
2815
+ "The file/media ID"
2266
2816
  fileId: SortEnumType @cost(weight: "10")
2267
- "The file\/media name"
2817
+ "The file/media name"
2268
2818
  fileName: SortEnumType @cost(weight: "10")
2269
2819
  "Total number of impressions that occurred during media playback"
2270
2820
  totalImpressions: SortEnumType @cost(weight: "10")
@@ -2298,9 +2848,9 @@ input AdHawkMediaPlayStatsFilterInput {
2298
2848
  fileName: StringOperationFilterInput
2299
2849
  "Total number of times this media was played"
2300
2850
  totalPlays: LongOperationFilterInput
2301
- "Total duration of all plays in milliseconds"
2851
+ "Total duration of all plays in seconds"
2302
2852
  totalDuration: LongOperationFilterInput
2303
- "Average play duration in milliseconds"
2853
+ "Average play duration in seconds"
2304
2854
  avgDuration: DecimalOperationFilterInput
2305
2855
  "Number of unique devices that played this media"
2306
2856
  deviceCount: LongOperationFilterInput
@@ -2314,15 +2864,15 @@ input AdHawkMediaPlayStatsSortInput {
2314
2864
  fileName: SortEnumType @cost(weight: "10")
2315
2865
  "Total number of times this media was played"
2316
2866
  totalPlays: SortEnumType @cost(weight: "10")
2317
- "Total duration of all plays in milliseconds"
2867
+ "Total duration of all plays in seconds"
2318
2868
  totalDuration: SortEnumType @cost(weight: "10")
2319
- "Average play duration in milliseconds"
2869
+ "Average play duration in seconds"
2320
2870
  avgDuration: SortEnumType @cost(weight: "10")
2321
2871
  "Number of unique devices that played this media"
2322
2872
  deviceCount: SortEnumType @cost(weight: "10")
2323
2873
  }
2324
2874
 
2325
- "Represents a device ping\/heartbeat log entry - records device health and status"
2875
+ "Represents a device ping/heartbeat log entry - records device health and status"
2326
2876
  input AdHawkPingLogFilterInput {
2327
2877
  and: [AdHawkPingLogFilterInput!]
2328
2878
  or: [AdHawkPingLogFilterInput!]
@@ -2356,7 +2906,7 @@ input AdHawkPingLogFilterInput {
2356
2906
  utcOffset: IntOperationFilterInput
2357
2907
  }
2358
2908
 
2359
- "Represents a device ping\/heartbeat log entry - records device health and status"
2909
+ "Represents a device ping/heartbeat log entry - records device health and status"
2360
2910
  input AdHawkPingLogSortInput {
2361
2911
  "Unique identifier for this ping log entry"
2362
2912
  id: SortEnumType @cost(weight: "10")
@@ -2402,7 +2952,7 @@ input AdHawkPlayLogFilterInput {
2402
2952
  fileId: StringOperationFilterInput
2403
2953
  "The name of the media file"
2404
2954
  fileName: StringOperationFilterInput
2405
- "Duration of the play in milliseconds"
2955
+ "Duration of the play in seconds"
2406
2956
  duration: IntOperationFilterInput
2407
2957
  "Type of play (internal use)"
2408
2958
  type: IntOperationFilterInput
@@ -2422,7 +2972,7 @@ input AdHawkPlayLogSortInput {
2422
2972
  fileId: SortEnumType @cost(weight: "10")
2423
2973
  "The name of the media file"
2424
2974
  fileName: SortEnumType @cost(weight: "10")
2425
- "Duration of the play in milliseconds"
2975
+ "Duration of the play in seconds"
2426
2976
  duration: SortEnumType @cost(weight: "10")
2427
2977
  "Type of play (internal use)"
2428
2978
  type: SortEnumType @cost(weight: "10")
@@ -2451,9 +3001,9 @@ input AdHawkPlayStatsByTimeFilterInput {
2451
3001
  periodEnd: DateTimeOperationFilterInput
2452
3002
  "Total number of plays during this period"
2453
3003
  totalPlays: LongOperationFilterInput
2454
- "Total duration of all plays in milliseconds"
3004
+ "Total duration of all plays in seconds"
2455
3005
  totalDuration: LongOperationFilterInput
2456
- "Average play duration in milliseconds"
3006
+ "Average play duration in seconds"
2457
3007
  avgDuration: DecimalOperationFilterInput
2458
3008
  "Number of unique devices (if aggregated by file)"
2459
3009
  deviceCount: LongOperationFilterInput
@@ -2480,9 +3030,9 @@ input AdHawkPlayStatsByTimeSortInput {
2480
3030
  periodEnd: SortEnumType @cost(weight: "10")
2481
3031
  "Total number of plays during this period"
2482
3032
  totalPlays: SortEnumType @cost(weight: "10")
2483
- "Total duration of all plays in milliseconds"
3033
+ "Total duration of all plays in seconds"
2484
3034
  totalDuration: SortEnumType @cost(weight: "10")
2485
- "Average play duration in milliseconds"
3035
+ "Average play duration in seconds"
2486
3036
  avgDuration: SortEnumType @cost(weight: "10")
2487
3037
  "Number of unique devices (if aggregated by file)"
2488
3038
  deviceCount: SortEnumType @cost(weight: "10")
@@ -2490,16 +3040,6 @@ input AdHawkPlayStatsByTimeSortInput {
2490
3040
  fileCount: SortEnumType @cost(weight: "10")
2491
3041
  }
2492
3042
 
2493
- "Input for adding a content source to a playlist."
2494
- input AddPlaylistSourceInput {
2495
- "The playlist ID to add the source to."
2496
- playlistId: String
2497
- "The source to add."
2498
- source: SourceInput
2499
- "Optional position (0-based index). If omitted, appends to end."
2500
- position: Int
2501
- }
2502
-
2503
3043
  "Device associated with an alert"
2504
3044
  input AlertDeviceFilterInput {
2505
3045
  and: [AlertDeviceFilterInput!]
@@ -2576,6 +3116,15 @@ input AlertSortInput {
2576
3116
  isActive: SortEnumType @cost(weight: "10")
2577
3117
  }
2578
3118
 
3119
+ """
3120
+ Inputs for approving a media asset. Approval is reversible — calling DeclineMedia
3121
+ on a previously approved file will move it back to declined state.
3122
+ """
3123
+ input ApproveMediaInput {
3124
+ "The media ID to approve."
3125
+ id: String
3126
+ }
3127
+
2579
3128
  "Audit event model representing account activity"
2580
3129
  input AuditEventFilterInput {
2581
3130
  and: [AuditEventFilterInput!]
@@ -2654,8 +3203,14 @@ input AuditEventSortInput {
2654
3203
  input BatchCreateDataTableRowsInput {
2655
3204
  "The table ID to add rows to."
2656
3205
  tableId: String
2657
- "Row data objects to create (max 100)."
2658
- rows: [JSON]
3206
+ """
3207
+ Row data objects to create (max 100). Each object follows the same key/value
3208
+ rules as `createDataTableRow.input.data` — keys must match column keys and
3209
+ values must match each column's declared `ColumnType` (MEDIA accepts an encrypted
3210
+ media id string, `{ "mediaId": "..." }`, or a fully-resolved `{ url, thumbnailUrl,
3211
+ name, mimeType }` object).
3212
+ """
3213
+ rows: [Any]
2659
3214
  }
2660
3215
 
2661
3216
  "Input for batch deleting rows."
@@ -2828,21 +3383,6 @@ input BulkCommandInput {
2828
3383
  commands: [CommandInput]
2829
3384
  }
2830
3385
 
2831
- input ByteOperationFilterInput {
2832
- eq: Byte @cost(weight: "10")
2833
- neq: Byte @cost(weight: "10")
2834
- in: [Byte] @cost(weight: "10")
2835
- nin: [Byte] @cost(weight: "10")
2836
- gt: Byte @cost(weight: "10")
2837
- ngt: Byte @cost(weight: "10")
2838
- gte: Byte @cost(weight: "10")
2839
- ngte: Byte @cost(weight: "10")
2840
- lt: Byte @cost(weight: "10")
2841
- nlt: Byte @cost(weight: "10")
2842
- lte: Byte @cost(weight: "10")
2843
- nlte: Byte @cost(weight: "10")
2844
- }
2845
-
2846
3386
  "A command to send to a device."
2847
3387
  input CommandInput {
2848
3388
  """
@@ -2914,7 +3454,7 @@ input CreateDataTableInput {
2914
3454
  groupId: String
2915
3455
  "Column definitions (at least one required)."
2916
3456
  columns: [DataTableColumnInput]
2917
- "Optional cache TTL in seconds for gadget\/player reads."
3457
+ "Optional cache TTL in seconds for gadget/player reads."
2918
3458
  cacheTtlSeconds: Int
2919
3459
  }
2920
3460
 
@@ -2922,8 +3462,20 @@ input CreateDataTableInput {
2922
3462
  input CreateDataTableRowInput {
2923
3463
  "The table ID to add the row to."
2924
3464
  tableId: String
2925
- "Row data as a JSON object. Keys must match column keys defined in the table schema."
2926
- data: JSON
3465
+ """
3466
+ Row data as a JSON object. Each key MUST match a `key` from the table's column
3467
+ definitions, and each value MUST match that column's `ColumnType` value rules
3468
+ (e.g. STRING → JSON string, NUMBER → JSON number, BOOLEAN → JSON true/false,
3469
+ DATE → ISO 8601 string, SELECT → a value from the column's `options`,
3470
+ MEDIA → encrypted media id string OR `{ "mediaId": "..." }` OR a fully-resolved
3471
+ `{ url, thumbnailUrl, name, mimeType }` object — the server normalizes id/id-object
3472
+ forms to the canonical object before storage).
3473
+
3474
+ Best practice for agents: query `dataTable(tableId: "…") { columns { key type required options } }`
3475
+ first to discover the schema, then construct `data` accordingly. Validation
3476
+ failures return structured details in `structuredValidationErrors`.
3477
+ """
3478
+ data: Any
2927
3479
  }
2928
3480
 
2929
3481
  "Input for creating a media asset by downloading from a URL."
@@ -2934,7 +3486,7 @@ input CreateMediaFromUrlInput {
2934
3486
  groupId: String
2935
3487
  "Display name for the media."
2936
3488
  name: String
2937
- "Optional description\/tags."
3489
+ "Optional description/tags."
2938
3490
  description: String
2939
3491
  "Whether to share with sub-accounts."
2940
3492
  shared: Boolean!
@@ -2952,16 +3504,20 @@ input DataTableColumnInput {
2952
3504
  name: String
2953
3505
  "Unique key used in row data objects."
2954
3506
  key: String
2955
- "Data type of the column."
3507
+ """
3508
+ Data type of the column. See the `ColumnType` enum value descriptions for the
3509
+ per-type row-value contract (e.g. MEDIA accepts an encrypted media id, an
3510
+ id-object, or a fully-resolved media object).
3511
+ """
2956
3512
  type: ColumnType!
2957
- "Whether a value is required for this column."
2958
- required: Boolean!
2959
- "Whether the column supports sorting."
2960
- sortable: Boolean!
3513
+ "Whether a value is required for this column. Defaults to false when omitted."
3514
+ required: Boolean
3515
+ "Whether the column supports sorting. Defaults to false when omitted."
3516
+ sortable: Boolean
2961
3517
  "Allowed values for Select-type columns."
2962
3518
  options: [String]
2963
3519
  "Default value for the column."
2964
- default: JSON
3520
+ default: Any
2965
3521
  }
2966
3522
 
2967
3523
  input DateTimeOperationFilterInput {
@@ -2994,6 +3550,17 @@ input DecimalOperationFilterInput {
2994
3550
  nlte: Decimal @cost(weight: "10")
2995
3551
  }
2996
3552
 
3553
+ """
3554
+ Inputs for declining a media asset. Decline is reversible — calling ApproveMedia
3555
+ on a previously declined file will move it back to approved state.
3556
+ """
3557
+ input DeclineMediaInput {
3558
+ "The media ID to decline."
3559
+ id: String
3560
+ "Optional reason recorded on the file for audit purposes."
3561
+ reason: String
3562
+ }
3563
+
2997
3564
  """
2998
3565
  Represents a digital signage player device in the RevelDigital platform.
2999
3566
  A device is a registered hardware unit that displays content according to assigned schedules and templates.
@@ -3023,9 +3590,9 @@ input DeviceFilterInput {
3023
3590
  languageCode: StringOperationFilterInput
3024
3591
  "The timestamp of the last content sync with the server"
3025
3592
  lastUpdate: DateTimeOperationFilterInput
3026
- "The physical location\/address of the device"
3593
+ "The physical location/address of the device"
3027
3594
  location: LocationFilterInput
3028
- "The device ping\/heartbeat data"
3595
+ "The device ping/heartbeat data"
3029
3596
  pingData: PingDataFilterInput
3030
3597
  "The device registration key"
3031
3598
  registrationKey: StringOperationFilterInput
@@ -3079,9 +3646,9 @@ input DeviceSortInput {
3079
3646
  languageCode: SortEnumType @cost(weight: "10")
3080
3647
  "The timestamp of the last content sync with the server"
3081
3648
  lastUpdate: SortEnumType @cost(weight: "10")
3082
- "The physical location\/address of the device"
3649
+ "The physical location/address of the device"
3083
3650
  location: LocationSortInput @cost(weight: "10")
3084
- "The device ping\/heartbeat data"
3651
+ "The device ping/heartbeat data"
3085
3652
  pingData: PingDataSortInput @cost(weight: "10")
3086
3653
  "The device registration key"
3087
3654
  registrationKey: SortEnumType @cost(weight: "10")
@@ -3295,13 +3862,6 @@ input KeyValuePairOfStringAndStringFilterInput {
3295
3862
  value: StringOperationFilterInput
3296
3863
  }
3297
3864
 
3298
- input ListByteOperationFilterInput {
3299
- all: ByteOperationFilterInput @cost(weight: "10")
3300
- none: ByteOperationFilterInput @cost(weight: "10")
3301
- some: ByteOperationFilterInput @cost(weight: "10")
3302
- any: Boolean @cost(weight: "10")
3303
- }
3304
-
3305
3865
  input ListFilterInputTypeOfAlertDeviceFilterInput {
3306
3866
  all: AlertDeviceFilterInput @cost(weight: "10")
3307
3867
  none: AlertDeviceFilterInput @cost(weight: "10")
@@ -3365,6 +3925,13 @@ input ListStringOperationFilterInput {
3365
3925
  any: Boolean @cost(weight: "10")
3366
3926
  }
3367
3927
 
3928
+ input ListUnsignedByteOperationFilterInput {
3929
+ all: UnsignedByteOperationFilterInput @cost(weight: "10")
3930
+ none: UnsignedByteOperationFilterInput @cost(weight: "10")
3931
+ some: UnsignedByteOperationFilterInput @cost(weight: "10")
3932
+ any: Boolean @cost(weight: "10")
3933
+ }
3934
+
3368
3935
  input LocationFilterInput {
3369
3936
  and: [LocationFilterInput!]
3370
3937
  or: [LocationFilterInput!]
@@ -3451,6 +4018,14 @@ input MediaFilterInput {
3451
4018
  width: IntOperationFilterInput
3452
4019
  "The height of the media"
3453
4020
  height: IntOperationFilterInput
4021
+ "Approval state. True = approved for playback, false = declined, null = pending review."
4022
+ isApproved: BooleanOperationFilterInput
4023
+ "Timestamp the media was approved, if applicable."
4024
+ approvedOn: DateTimeOperationFilterInput
4025
+ "Timestamp the media was declined, if applicable."
4026
+ declinedOn: DateTimeOperationFilterInput
4027
+ "Reason recorded when the media was declined, if any."
4028
+ declinedReason: StringOperationFilterInput
3454
4029
  "The media name"
3455
4030
  name: StringOperationFilterInput
3456
4031
  "The group id"
@@ -3496,6 +4071,14 @@ input MediaSortInput {
3496
4071
  width: SortEnumType @cost(weight: "10")
3497
4072
  "The height of the media"
3498
4073
  height: SortEnumType @cost(weight: "10")
4074
+ "Approval state. True = approved for playback, false = declined, null = pending review."
4075
+ isApproved: SortEnumType @cost(weight: "10")
4076
+ "Timestamp the media was approved, if applicable."
4077
+ approvedOn: SortEnumType @cost(weight: "10")
4078
+ "Timestamp the media was declined, if applicable."
4079
+ declinedOn: SortEnumType @cost(weight: "10")
4080
+ "Reason recorded when the media was declined, if any."
4081
+ declinedReason: SortEnumType @cost(weight: "10")
3499
4082
  "The media name"
3500
4083
  name: SortEnumType @cost(weight: "10")
3501
4084
  "The group id"
@@ -3573,7 +4156,7 @@ input PingDataFilterInput {
3573
4156
  "Ping type"
3574
4157
  type: StringOperationFilterInput
3575
4158
  "Snapshot (screenshot) of live player content"
3576
- snap: ListByteOperationFilterInput
4159
+ snap: ListUnsignedByteOperationFilterInput
3577
4160
  "Player version number"
3578
4161
  playerVersion: StringOperationFilterInput
3579
4162
  "Player OS version"
@@ -4170,6 +4753,21 @@ input TemplateSortInput {
4170
4753
  orientation: SortEnumType @cost(weight: "10")
4171
4754
  }
4172
4755
 
4756
+ input UnsignedByteOperationFilterInput {
4757
+ eq: UnsignedByte @cost(weight: "10")
4758
+ neq: UnsignedByte @cost(weight: "10")
4759
+ in: [UnsignedByte] @cost(weight: "10")
4760
+ nin: [UnsignedByte] @cost(weight: "10")
4761
+ gt: UnsignedByte @cost(weight: "10")
4762
+ ngt: UnsignedByte @cost(weight: "10")
4763
+ gte: UnsignedByte @cost(weight: "10")
4764
+ ngte: UnsignedByte @cost(weight: "10")
4765
+ lt: UnsignedByte @cost(weight: "10")
4766
+ nlt: UnsignedByte @cost(weight: "10")
4767
+ lte: UnsignedByte @cost(weight: "10")
4768
+ nlte: UnsignedByte @cost(weight: "10")
4769
+ }
4770
+
4173
4771
  """
4174
4772
  Input for updating an existing data table definition.
4175
4773
  Only provided fields are changed.
@@ -4195,8 +4793,18 @@ input UpdateDataTableRowInput {
4195
4793
  tableId: String
4196
4794
  "The row ID to update."
4197
4795
  rowId: String
4198
- "Partial row data. Only provided keys are updated."
4199
- data: JSON
4796
+ """
4797
+ Partial row data. Only provided keys are updated; omitted keys are left unchanged.
4798
+ Each provided key MUST match a column `key` from the table schema, and each value
4799
+ MUST match that column's `ColumnType` value rules. For MEDIA columns you may pass
4800
+ an encrypted media id string, `{ "mediaId": "..." }`, or a fully-resolved
4801
+ `{ url, thumbnailUrl, name, mimeType }` object — id/id-object forms are
4802
+ normalized server-side to the canonical object before storage.
4803
+
4804
+ Best practice for agents: use the row's current `eTag` (from `dataTableRow` or
4805
+ a prior mutation result) in the `eTag` argument below to prevent lost updates.
4806
+ """
4807
+ data: Any
4200
4808
  "Optional ETag for optimistic concurrency. Pass the row's current ETag to prevent conflicting writes."
4201
4809
  eTag: String
4202
4810
  }
@@ -4207,7 +4815,7 @@ input UpdateMediaInput {
4207
4815
  id: String
4208
4816
  "New name. Null leaves unchanged."
4209
4817
  name: String
4210
- "New description\/tags. Null leaves unchanged."
4818
+ "New description/tags. Null leaves unchanged."
4211
4819
  description: String
4212
4820
  "New start date. Null leaves unchanged."
4213
4821
  startDate: DateTime
@@ -4359,16 +4967,33 @@ enum ApplyPolicy {
4359
4967
  VALIDATION
4360
4968
  }
4361
4969
 
4970
+ "Logical type of a data table column. Determines how row `data` values are validated and stored. Use the value descriptions below to choose the right type for each column."
4362
4971
  enum ColumnType {
4972
+ "Scalar text up to 1000 characters. Row values must be JSON strings."
4363
4973
  STRING
4974
+ "JSON number (integer or floating-point). Row values must be JSON numbers, not numeric strings."
4364
4975
  NUMBER
4976
+ "JSON boolean. Row values must be true or false (not the strings \"true\"/\"false\")."
4365
4977
  BOOLEAN
4978
+ "ISO 8601 date or date-time string (e.g. \"2025-01-31\" or \"2025-01-31T12:34:56Z\")."
4366
4979
  DATE
4980
+ "One of a fixed list of strings. The column's `options` array MUST be supplied at table creation; row values must exactly match one of those options."
4367
4981
  SELECT
4982
+ """
4983
+ Reference to a media asset (image or video). Row values may be supplied in any of three shapes — the server normalizes them to the canonical object below before storage so the CMS grid and players can render them:
4984
+ 1. **Encrypted media id (string)** — e.g. "AbCd1234...". The server looks up the asset and expands it into the canonical shape. This is the recommended form for API/agent callers.
4985
+ 2. **Id-bearing object** — `{ "mediaId": "<encrypted id>" }` (any extra fields you supply, e.g. `caption`, are preserved). Resolved the same way as a bare id.
4986
+ 3. **Canonical object** (what the CMS UI writes) — `{ "url": "<absolute CDN URL>", "thumbnailUrl": "<absolute thumb URL>", "name": "<display name>", "mimeType": "<MIME type>" }`. Passed through as-is when `url` is already populated.
4987
+ After normalization, `thumbnailUrl` is what the grid renders and `url` is what the player consumes. Unresolved ids (asset not found / not in account) are left as-supplied; required-field validation will then surface the failure. Empty / null clears the cell.
4988
+ """
4368
4989
  MEDIA
4990
+ "Absolute URL string (must include scheme, e.g. https://example.com)."
4369
4991
  URL
4370
- RICH_TEXT
4992
+ "Rich-text HTML/markdown string. No length cap; row values must be JSON strings."
4993
+ RICHTEXT
4994
+ "Time-of-day string parseable as TimeSpan (e.g. \"14:30\", \"14:30:00\")."
4371
4995
  TIME
4996
+ "Scalar text up to 1000 characters, not shown in default UI listings. Same value rules as STRING."
4372
4997
  HIDDEN
4373
4998
  }
4374
4999
 
@@ -4713,7 +5338,7 @@ enum SourceType {
4713
5338
  COMMAND
4714
5339
  "Adobe Flash content (SWF). Legacy format with limited device support."
4715
5340
  FLASH
4716
- "Interactive gadget\/widget. Custom HTML5 applications with RevelDigital gadget API integration."
5341
+ "Interactive gadget/widget. Custom HTML5 applications with RevelDigital gadget API integration."
4717
5342
  GADGET
4718
5343
  "Static image display (JPEG, PNG, GIF, BMP). Most widely supported content type."
4719
5344
  IMAGE
@@ -4725,15 +5350,15 @@ enum SourceType {
4725
5350
  PLAYLIST
4726
5351
  "Microsoft PowerPoint presentation. Legacy format, converted to images on upload."
4727
5352
  POWER_POINT
4728
- "RSS\/Atom feed display. Renders feed items as scrolling text or formatted content."
5353
+ "RSS/Atom feed display. Renders feed items as scrolling text or formatted content."
4729
5354
  RSS
4730
5355
  "SVG vector graphic. Scalable graphics that render crisply at any resolution."
4731
5356
  SVG
4732
5357
  "Embedded template. Displays a full template layout as a source within a playlist."
4733
5358
  TEMPLATE
4734
- "Plain text content for ticker\/marquee display. Scrolls horizontally or vertically."
5359
+ "Plain text content for ticker/marquee display. Scrolls horizontally or vertically."
4735
5360
  TEXT
4736
- "Twitter\/X feed integration. Displays tweets from specified accounts or hashtags."
5361
+ "Twitter/X feed integration. Displays tweets from specified accounts or hashtags."
4737
5362
  TWITTER
4738
5363
  "URL redirect or web link. Opens specified URL in the content zone."
4739
5364
  URL
@@ -4750,27 +5375,53 @@ enum SourceType {
4750
5375
  YOU_TUBE
4751
5376
  "Extended Vistar Media integration with additional targeting and reporting features."
4752
5377
  VISTAR_MEDIA_EX
5378
+ "Data table content. Each row is extrapolated into individual text entries for ticker/marquee display."
5379
+ DATA_TABLE
4753
5380
  }
4754
5381
 
4755
- "The authorize directive."
4756
- directive @authorize("The name of the authorization policy that determines access to the annotated resource." policy: String "Roles that are allowed to access the annotated resource." roles: [String!] "Defines when when the authorize directive shall be applied.By default the authorize directives are applied during the validation phase." apply: ApplyPolicy! = BEFORE_RESOLVER) repeatable on OBJECT | FIELD_DEFINITION
4757
-
4758
- "The purpose of the `cost` directive is to define a `weight` for GraphQL types, fields, and arguments. Static analysis can use these weights when calculating the overall cost of a query or response."
4759
- directive @cost("The `weight` argument defines what value to add to the overall cost for every appearance, or possible appearance, of a type, field, argument, etc." weight: String!) on SCALAR | OBJECT | FIELD_DEFINITION | ARGUMENT_DEFINITION | ENUM | INPUT_FIELD_DEFINITION
4760
-
4761
- "The `@specifiedBy` directive is used within the type system definition language to provide a URL for specifying the behavior of custom scalar definitions."
4762
- directive @specifiedBy("The specifiedBy URL points to a human-readable specification. This field will only read a result for scalar types." url: String!) on SCALAR
5382
+ "Machine-readable code identifying the kind of validation failure."
5383
+ enum ValidationErrorCode {
5384
+ "A required field was missing from the row data."
5385
+ REQUIRED
5386
+ "The value's JSON type did not match the column's declared type."
5387
+ INVALID_TYPE
5388
+ "The value violated a length, range, or option constraint."
5389
+ OUT_OF_RANGE
5390
+ "The value could not be parsed (e.g. invalid ISO 8601 date, malformed URL)."
5391
+ INVALID_FORMAT
5392
+ "Catch-all when no more specific code applies."
5393
+ INVALID
5394
+ }
4763
5395
 
4764
- "The `Byte` scalar type represents non-fractional whole numeric values. Byte can represent values between 0 and 255."
4765
- scalar Byte
5396
+ "The `Any` scalar type represents any valid GraphQL value."
5397
+ scalar Any @specifiedBy(url: "https://scalars.graphql.org/chillicream/any.html")
4766
5398
 
4767
- "The `DateTime` scalar represents an ISO-8601 compliant date time type."
4768
- scalar DateTime @specifiedBy(url: "https:\/\/www.graphql-scalars.com\/date-time")
5399
+ "The `DateTime` scalar type represents a date and time with time zone offset information."
5400
+ scalar DateTime
5401
+ @specifiedBy(url: "https://scalars.graphql.org/chillicream/date-time.html")
4769
5402
 
4770
- "The `Decimal` scalar type represents a decimal floating-point number."
5403
+ "The `Decimal` scalar type represents a decimal floating-point number with high precision."
4771
5404
  scalar Decimal
5405
+ @specifiedBy(url: "https://scalars.graphql.org/chillicream/decimal.html")
5406
+
5407
+ "The `Long` scalar type represents a signed 64-bit integer."
5408
+ scalar Long
5409
+ @specifiedBy(url: "https://scalars.graphql.org/chillicream/long.html")
4772
5410
 
4773
- scalar JSON
5411
+ "The `UnsignedByte` scalar type represents an unsigned 8-bit integer."
5412
+ scalar UnsignedByte
5413
+ @specifiedBy(
5414
+ url: "https://scalars.graphql.org/chillicream/unsigned-byte.html"
5415
+ )
4774
5416
 
4775
- "The `Long` scalar type represents non-fractional signed whole 64-bit numeric values. Long can represent values between -(2^63) and 2^63 - 1."
4776
- scalar Long
5417
+ "The purpose of the `cost` directive is to define a `weight` for GraphQL types, fields, and arguments. Static analysis can use these weights when calculating the overall cost of a query or response."
5418
+ directive @cost(
5419
+ "The `weight` argument defines what value to add to the overall cost for every appearance, or possible appearance, of a type, field, argument, etc."
5420
+ weight: String!
5421
+ ) on
5422
+ | SCALAR
5423
+ | OBJECT
5424
+ | FIELD_DEFINITION
5425
+ | ARGUMENT_DEFINITION
5426
+ | ENUM
5427
+ | INPUT_FIELD_DEFINITION