@trillboards/api-client 0.1.3 → 0.3.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.
package/dist/index.d.ts CHANGED
@@ -173,6 +173,32 @@ interface HttpClientConfig {
173
173
  baseUrl: string;
174
174
  version?: string;
175
175
  }
176
+ interface RetryOptions {
177
+ /** Maximum number of retry attempts after the initial call. Defaults to 6. */
178
+ retries?: number;
179
+ /** Base delay in ms for exponential backoff. Defaults to 1000. */
180
+ baseMs?: number;
181
+ /**
182
+ * Optional callback invoked when an attempt fails with a retryable error.
183
+ * `attempt` is 1-indexed (1 = first failure). Useful for observability —
184
+ * the CTV SDK uses this to emit `upload_error` events without coupling
185
+ * the retry loop to event emission.
186
+ */
187
+ onAttemptError?: (attempt: number, error: unknown) => void;
188
+ }
189
+ /**
190
+ * Wrap an async operation in retry-with-exponential-backoff.
191
+ *
192
+ * - Retries up to `retries` times on retryable errors (429, 5xx, TypeError network).
193
+ * - Honors `Retry-After` header on 429 responses (parsed into TrillboardsError.retryAfter).
194
+ * - Throws the last error after the budget is exhausted.
195
+ * - Permanent 4xx (auth, validation, not-found) throw immediately on first attempt.
196
+ *
197
+ * This is the SINGLE retry primitive in the SDK — every POST/PUT/DELETE is
198
+ * wrapped automatically by HttpClient. GET is left to the caller because
199
+ * idempotency assumptions vary by route.
200
+ */
201
+ declare function retryWithBackoff<T>(operation: () => Promise<T>, opts?: RetryOptions): Promise<T>;
176
202
  declare class HttpClient {
177
203
  private readonly config;
178
204
  constructor(config: HttpClientConfig);
@@ -180,10 +206,33 @@ declare class HttpClient {
180
206
  get<T>(path: string, opts?: {
181
207
  params?: Record<string, unknown>;
182
208
  }): Promise<T>;
183
- post<T>(path: string, body?: unknown): Promise<T>;
184
- put<T>(path: string, body?: unknown): Promise<T>;
185
- patch<T>(path: string, body?: unknown): Promise<T>;
186
- delete<T>(path: string): Promise<T>;
209
+ /**
210
+ * POST / PUT / PATCH / DELETE auto-retry on 429 + 5xx + network TypeError
211
+ * via `retryWithBackoff()`. Callers can opt into observability by passing
212
+ * `retry.onAttemptError` to receive a callback per transient failure.
213
+ *
214
+ * The retry behavior is identical across all four methods because all of
215
+ * them are state-changing operations subject to the same transient-failure
216
+ * classes (rate limit, upstream-down, network-flap). The wire idempotency
217
+ * of POST vs DELETE is enforced server-side via Idempotency-Key headers,
218
+ * which the caller can attach via `opts.headers`.
219
+ */
220
+ post<T>(path: string, body?: unknown, opts?: {
221
+ retry?: RetryOptions;
222
+ headers?: Record<string, string>;
223
+ }): Promise<T>;
224
+ put<T>(path: string, body?: unknown, opts?: {
225
+ retry?: RetryOptions;
226
+ headers?: Record<string, string>;
227
+ }): Promise<T>;
228
+ patch<T>(path: string, body?: unknown, opts?: {
229
+ retry?: RetryOptions;
230
+ headers?: Record<string, string>;
231
+ }): Promise<T>;
232
+ delete<T>(path: string, opts?: {
233
+ retry?: RetryOptions;
234
+ headers?: Record<string, string>;
235
+ }): Promise<T>;
187
236
  private buildUrl;
188
237
  }
189
238
 
@@ -257,8 +306,17 @@ declare class DevicesClient {
257
306
  delete(deviceId: string): Promise<{
258
307
  success: boolean;
259
308
  }>;
260
- /** Send heartbeat for a device. */
261
- heartbeat(deviceId: string, body?: Record<string, unknown>): Promise<{
309
+ /**
310
+ * Send heartbeat for a device.
311
+ *
312
+ * Auto-retries on 429 + 5xx + network TypeError via the shared
313
+ * retryWithBackoff() helper (see http.ts). Pass `opts.retry.onAttemptError`
314
+ * to observe transient failures (e.g. emit an `upload_error` event from
315
+ * the CTV SDK without coupling the retry loop to its event emitter).
316
+ */
317
+ heartbeat(deviceId: string, body?: Record<string, unknown>, opts?: {
318
+ retry?: RetryOptions;
319
+ }): Promise<{
262
320
  success: boolean;
263
321
  }>;
264
322
  }
@@ -600,39 +658,126 @@ declare class TrillboardsError extends Error {
600
658
  }
601
659
 
602
660
  /**
603
- * Webhook signature verification for Trillboards Partner API webhooks.
661
+ * Webhook signature verification for Trillboards webhooks.
662
+ *
663
+ * Header format produced by the server (matches Stripe-style compound shape):
604
664
  *
605
- * Uses HMAC-SHA256 with timing-safe comparison to prevent signature
606
- * forgery and timing attacks.
665
+ * X-Trillboards-Signature: t=<unix_seconds>,v0=<hex>,v1=<hex>
666
+ * X-Trillboards-Timestamp: <unix_seconds> // redundant; same value as t=
667
+ * X-Trillboards-Event: <event_name>
668
+ * X-Trillboards-Webhook-Id: <subscription_id>
669
+ *
670
+ * Where v1 = HMAC-SHA256(secret, `${timestamp}.${payload}`)
671
+ * v0 = HMAC-SHA256(secret, payload) ← legacy body-only, emitted for back-compat
672
+ *
673
+ * `constructEvent` prefers v1 (replay-protected); falls back to v0 when v1 is
674
+ * absent (server in pre-migration state) or when only the legacy
675
+ * `sha256=<hex>` form is present.
676
+ *
677
+ * Replay protection: a configurable tolerance window (default 300s, Stripe-
678
+ * aligned) rejects payloads whose timestamp is too far from the verifier's
679
+ * clock. Adjust via the `tolerance` option.
680
+ *
681
+ * Migration note (since 0.3.0):
682
+ * The 0.2.0-shape `constructEvent(payload, signatureString, secret)` is kept
683
+ * as `constructEventLegacy` for one minor version. It does NOT verify the
684
+ * timestamp (the 0.2.0 verifier had no access to one). Migrate to the new
685
+ * call shape `constructEvent(payload, req.headers, secret)` to gain replay
686
+ * protection and compound-header support.
607
687
  */
608
688
 
689
+ interface ConstructEventOptions {
690
+ /** Maximum allowed age (seconds) of a signed payload. Default 300 (Stripe-aligned). */
691
+ tolerance?: number;
692
+ /** Override the verifier's current time (seconds). Tests only. */
693
+ nowSec?: number;
694
+ }
695
+ /**
696
+ * Headers carried by a Trillboards webhook delivery. Accepts either the
697
+ * canonical Node `IncomingHttpHeaders` shape (lowercase keys) or any
698
+ * Record<string, string|string[]> with case-insensitive lookup.
699
+ */
700
+ type WebhookHeaders = Record<string, string | string[] | undefined> | {
701
+ [key: string]: string | string[] | undefined;
702
+ };
703
+ /**
704
+ * Parsed signature-header components.
705
+ */
706
+ interface ParsedSignatureHeader {
707
+ /** Unix seconds from `t=` if present. */
708
+ timestamp?: number;
709
+ /** Algorithm → hex-digest map. Standard keys: `v0`, `v1`. */
710
+ versions: Map<string, string>;
711
+ /** Set when the raw input matched the legacy `sha256=<hex>` shape. */
712
+ legacy?: string;
713
+ }
714
+ /**
715
+ * Parse a Trillboards `X-Trillboards-Signature` header into its component
716
+ * algorithm-keyed digests.
717
+ *
718
+ * Accepts:
719
+ * "t=<ts>,v1=<hex>" → canonical
720
+ * "t=<ts>,v0=<hex>,v1=<hex>" → canonical with legacy companion
721
+ * "sha256=<hex>" → pre-migration emitter (single value)
722
+ *
723
+ * @public
724
+ */
725
+ declare function parseSignatureHeader(rawSig: string): ParsedSignatureHeader;
609
726
  /**
610
727
  * Verify a webhook payload signature and parse the event.
611
728
  *
612
- * @param payload - Raw request body as string or Buffer.
613
- * @param signature - The signature from the `X-Trillboards-Signature` header.
614
- * @param secret - The webhook secret from your webhook subscription.
615
- * @returns The parsed WebhookEvent if signature is valid.
616
- * @throws TrillboardsError if the signature does not match.
729
+ * @param payload — raw request body (string or Buffer). Must be EXACTLY the
730
+ * bytes the server signed — do NOT re-stringify after JSON.parse.
731
+ * @param headers — IncomingHttpHeaders or any Record<string, string|string[]>
732
+ * produced by your HTTP framework. Case-insensitive lookup.
733
+ * For Express, pass `req.headers`. For Next.js, `req.headers`.
734
+ * Backwards-compat: a raw signature string (the 0.2.0 shape)
735
+ * is also accepted and parsed as if it were the value of
736
+ * `X-Trillboards-Signature`; in that case the verifier looks
737
+ * for the timestamp in the compound header itself, OR throws.
738
+ * @param secret — webhook subscription secret (whsec_...).
739
+ * @param opts.tolerance — replay-window in seconds. Default 300.
740
+ * @returns parsed WebhookEvent if signature valid AND timestamp within tolerance.
741
+ * @throws TrillboardsError(authentication_error / webhook_signature_invalid)
617
742
  *
618
743
  * @example
619
- * ```typescript
620
744
  * import { Webhooks } from '@trillboards/api-client';
621
745
  *
622
- * app.post('/webhooks', (req, res) => {
623
- * const event = Webhooks.constructEvent(
624
- * req.body,
625
- * req.headers['x-trillboards-signature'],
626
- * process.env.WEBHOOK_SECRET
627
- * );
628
- * console.log('Received event:', event.type);
629
- * res.sendStatus(200);
746
+ * app.post('/webhooks', express.raw({ type: 'application/json' }), (req, res) => {
747
+ * try {
748
+ * const event = Webhooks.constructEvent(
749
+ * req.body, // raw Buffer or string
750
+ * req.headers, // IncomingHttpHeaders
751
+ * process.env.WEBHOOK_SECRET!, // your subscription secret
752
+ * );
753
+ * console.log('Received', event.type);
754
+ * res.sendStatus(200);
755
+ * } catch (err) {
756
+ * // TrillboardsError with code "webhook_signature_invalid"
757
+ * res.sendStatus(401);
758
+ * }
630
759
  * });
631
- * ```
632
760
  */
633
- declare function constructEvent(payload: string | Buffer, signature: string, secret: string): WebhookEvent;
761
+ declare function constructEvent(payload: string | Buffer, headers: WebhookHeaders | string, secret: string, opts?: ConstructEventOptions): WebhookEvent;
762
+ /**
763
+ * @deprecated since 0.3.0 — kept for one minor version for partners stuck on
764
+ * the 0.2.0 call shape. Use `constructEvent(payload, req.headers, secret)`
765
+ * instead — it gains replay protection and compound-header support.
766
+ *
767
+ * Reproduces the 0.2.0 verifier exactly:
768
+ * HMAC-SHA256(secret, payload) compared (constant-time) against the
769
+ * supplied raw-hex signature string.
770
+ *
771
+ * Does NOT verify any timestamp. The 0.2.0 SDK never had access to one and
772
+ * silently accepted any age of payload — that is a vulnerability this
773
+ * legacy shim preserves only for migration compatibility.
774
+ */
775
+ declare function constructEventLegacy(payload: string | Buffer, signature: string, secret: string): WebhookEvent;
776
+ /** Namespaced export — matches the Stripe-style API. */
634
777
  declare const Webhooks: {
635
778
  constructEvent: typeof constructEvent;
779
+ constructEventLegacy: typeof constructEventLegacy;
780
+ parseSignatureHeader: typeof parseSignatureHeader;
636
781
  };
637
782
 
638
783
  /**
@@ -641,6 +786,389 @@ declare const Webhooks: {
641
786
  */
642
787
  declare const VERSION = "0.1.3";
643
788
 
644
- declare const generatedTypes: {};
789
+ type BleScanResultData = {
790
+ appleContinuitySubtype?: number | null;
791
+ deviceType?: number | null;
792
+ ibeaconMajor?: number | null;
793
+ ibeaconMinor?: number | null;
794
+ ibeaconUuid?: string | null;
795
+ manufacturerCompanyId?: number | null;
796
+ rawAddress: string;
797
+ rssi: number;
798
+ serviceUuids?: Array<string> | null;
799
+ stableManufacturerPayloadHex?: string | null;
800
+ txPowerDbm?: number | null;
801
+ [key: string]: unknown;
802
+ };
803
+ type DeviceCapabilityPayload = {
804
+ agentType?: string | null;
805
+ agentVersion?: string | null;
806
+ audienceSensing?: {
807
+ cameraAvailable?: boolean | null;
808
+ cameraCount?: number | null;
809
+ cameraHealth?: {
810
+ lastFailureClass?: string | null;
811
+ lastFailureMessage?: string | null;
812
+ lastFrameAtMs?: number | null;
813
+ retryCount?: number | null;
814
+ state?: string | null;
815
+ [key: string]: unknown;
816
+ } | null;
817
+ cameraType?: string | null;
818
+ microphoneAvailable?: boolean | null;
819
+ sensingMode?: string | null;
820
+ [key: string]: unknown;
821
+ } | null;
822
+ audioControl?: {
823
+ mute?: boolean | null;
824
+ volume?: boolean | null;
825
+ [key: string]: unknown;
826
+ } | null;
827
+ capabilitiesVersion?: number | null;
828
+ environmentSensors?: {
829
+ ambientLight?: boolean | null;
830
+ temperature?: boolean | null;
831
+ [key: string]: unknown;
832
+ } | null;
833
+ inputControl?: {
834
+ appSwitch?: boolean | null;
835
+ hdmi?: boolean | null;
836
+ [key: string]: unknown;
837
+ } | null;
838
+ isDeviceOwner?: boolean | null;
839
+ managementCapabilities?: {
840
+ clearCache?: boolean | null;
841
+ installApk?: boolean | null;
842
+ kioskMode?: boolean | null;
843
+ reboot?: boolean | null;
844
+ restart?: boolean | null;
845
+ screenshot?: boolean | null;
846
+ wipe?: boolean | null;
847
+ [key: string]: unknown;
848
+ } | null;
849
+ mlCapabilities?: {
850
+ availableRamMb?: number | null;
851
+ chipsetName?: string | null;
852
+ chipsetVendor?: string | null;
853
+ cpuAbi?: string | null;
854
+ densityDpi?: number | null;
855
+ gpuDelegateSupported?: boolean | null;
856
+ gpuName?: string | null;
857
+ hasNpu?: boolean | null;
858
+ maxVlmSizeMb?: number | null;
859
+ nnapiSupported?: boolean | null;
860
+ npuName?: string | null;
861
+ osApiLevel?: number | null;
862
+ recommendedModelTier?: string | null;
863
+ screenHeightPx?: number | null;
864
+ screenWidthPx?: number | null;
865
+ totalRamMb?: number | null;
866
+ [key: string]: unknown;
867
+ } | null;
868
+ powerControl?: {
869
+ cec?: boolean | null;
870
+ softBlackout?: boolean | null;
871
+ wol?: boolean | null;
872
+ [key: string]: unknown;
873
+ } | null;
874
+ wifiCsiSensing?: {
875
+ csiAvailable?: boolean | null;
876
+ csiHardwareType?: string | null;
877
+ csiNodeCount?: number | null;
878
+ [key: string]: unknown;
879
+ } | null;
880
+ [key: string]: unknown;
881
+ };
882
+ type HttpProbeResult = {
883
+ host: string;
884
+ port?: number | null;
885
+ server?: string | null;
886
+ [key: string]: unknown;
887
+ };
888
+ type MdnsNetworkDevice = {
889
+ host?: string | null;
890
+ instanceName: string;
891
+ mdnsModel?: string | null;
892
+ mdnsSoftwareVersion?: string | null;
893
+ mdnsVendor?: string | null;
894
+ port?: number | null;
895
+ serviceType: string;
896
+ [key: string]: unknown;
897
+ };
898
+ type PartnerAdDeliveryProfile = {
899
+ android_api_level?: number | null;
900
+ auto_recovery_enabled?: boolean;
901
+ ima_integration?: "android_native" | "html5_webview" | "disabled" | "unknown";
902
+ mode?: "ima_sdk" | "vast_fallback";
903
+ notes?: Array<string>;
904
+ reason?: string;
905
+ webview_chromium_major?: number | null;
906
+ };
907
+ /**
908
+ * Heartbeat payload from agent-core / agent-core-lite Android partner
909
+ * SDKs. Only includes fields verified populated in production
910
+ * `signal_observations` (last 30 days). Stub fields wired in Kotlin but
911
+ * never observed in CH are intentionally excluded; re-add only after
912
+ * telemetry confirms >1% population over 7 days.
913
+ *
914
+ */
915
+ type PartnerDeviceHeartbeatBody = {
916
+ advertisingId?: string | null;
917
+ advertisingIdType?: "gaid" | "idfa" | null | null;
918
+ bleDeviceCount?: number;
919
+ capabilities?: DeviceCapabilityPayload;
920
+ discoveredNetworkDevices?: Array<MdnsNetworkDevice> | null;
921
+ fingerprint?: string;
922
+ gatewayIpHash?: string | null;
923
+ httpProbes?: Array<HttpProbeResult> | null;
924
+ limitAdTracking?: boolean | null;
925
+ metadata?: Record<string, unknown>;
926
+ /** Capped at 50 devices (RSSI-sorted, strongest first). */
927
+ nearbyBleDevices?: Array<BleScanResultData> | null;
928
+ nearbyWifiNetworks?: Array<WifiScanResult> | null;
929
+ networkDeviceCount?: number;
930
+ /** Heartbeat schema version (1=baseline, 2=nativeSensorSnapshot) */
931
+ schemaVersion?: number;
932
+ screenId?: string | null;
933
+ /** Per-source skip-reason counter map. Shape `{source: {reason: count}}`. */
934
+ skipReasonCounts?: Record<string, Record<string, number>>;
935
+ ssdpDevices?: Array<SsdpDeviceInfo> | null;
936
+ status?: string;
937
+ wifiBssidHash?: string | null;
938
+ wifiEnvironment?: WifiEnvironmentSnapshot;
939
+ wifiNetworkCount?: number;
940
+ wifiSsidHash?: string | null;
941
+ [key: string]: unknown;
942
+ };
943
+ type PartnerHeartbeatCommand = {
944
+ /** Command normalized for partner SDK compatibility. */
945
+ command?: string;
946
+ id?: string;
947
+ payload?: Record<string, unknown>;
948
+ queued_at?: string;
949
+ };
950
+ type PartnerHeartbeatData = {
951
+ ad_delivery_profile?: PartnerAdDeliveryProfile;
952
+ commands?: Array<PartnerHeartbeatCommand>;
953
+ last_seen_at?: string;
954
+ status?: "online" | "offline";
955
+ };
956
+ type PartnerHeartbeatMeasurementMetadata = {
957
+ ageSeconds?: number | null;
958
+ cachedAt?: string | null;
959
+ receivedAt?: string | null;
960
+ source?: "redis_twin" | "pg_fallback" | "unknown";
961
+ [key: string]: unknown;
962
+ };
963
+ type PartnerHeartbeatQueryData = {
964
+ adDeliveryProfile?: PartnerAdDeliveryProfile;
965
+ deviceId: string;
966
+ lastHeartbeatAt?: string | null;
967
+ measurementMetadata?: PartnerHeartbeatMeasurementMetadata;
968
+ stalenessSeconds?: number | null;
969
+ telemetry?: PartnerSafeHeartbeatTelemetry;
970
+ [key: string]: unknown;
971
+ };
972
+ type PartnerHeartbeatQueryResponse = {
973
+ data?: PartnerHeartbeatQueryData;
974
+ success?: boolean;
975
+ };
976
+ /**
977
+ * Optional heartbeat payload. Nested telemetry objects are preferred; legacy flat keys
978
+ * are still accepted for backward compatibility.
979
+ *
980
+ */
981
+ type PartnerHeartbeatRequest = {
982
+ ad?: {
983
+ last_vast_request_at?: string;
984
+ last_vast_response_at?: string;
985
+ proof_of_play_enabled?: boolean;
986
+ };
987
+ agent_status?: string;
988
+ agent_version?: string;
989
+ android_api_level?: number;
990
+ brightness?: number;
991
+ desugaring_enabled?: boolean;
992
+ device?: {
993
+ android_api_level?: number;
994
+ make?: string;
995
+ model?: string;
996
+ os?: string;
997
+ osv?: string;
998
+ webview_chromium_major?: number;
999
+ };
1000
+ ima_integration?: "android_native" | "html5_webview" | "disabled" | "unknown";
1001
+ ima_sdk_version?: string;
1002
+ ima_support_reason?: string;
1003
+ ima_supported?: boolean;
1004
+ input_source?: string;
1005
+ last_ima_error_code?: number;
1006
+ last_vast_error_code?: number;
1007
+ last_vast_request_at?: string;
1008
+ last_vast_response_at?: string;
1009
+ /** Alternate namespace for telemetry keys (legacy support). */
1010
+ metadata?: Record<string, unknown>;
1011
+ muted?: boolean;
1012
+ network?: {
1013
+ bandwidthMbps?: number;
1014
+ connectionType?: string;
1015
+ downlinkMbps?: number;
1016
+ effectiveType?: string;
1017
+ latencyRtt?: number;
1018
+ rtt?: number;
1019
+ saveData?: boolean;
1020
+ };
1021
+ network_strength_dbm?: number;
1022
+ power_state?: "on" | "standby" | "off" | "unknown";
1023
+ proof_of_play_enabled?: boolean;
1024
+ sdk?: {
1025
+ android_api_level?: number;
1026
+ desugaring_enabled?: boolean;
1027
+ ima_integration?: "android_native" | "html5_webview" | "disabled" | "unknown";
1028
+ ima_sdk_version?: string;
1029
+ ima_supported?: boolean;
1030
+ version?: string;
1031
+ webview_chromium_major?: number;
1032
+ };
1033
+ sdk_version?: string;
1034
+ telemetry?: PartnerHeartbeatTelemetry;
1035
+ temperature_c?: number;
1036
+ uptime_seconds?: number;
1037
+ volume?: number;
1038
+ webview_chromium_major?: number;
1039
+ };
1040
+ type PartnerHeartbeatResponse = {
1041
+ data?: PartnerHeartbeatData;
1042
+ success?: boolean;
1043
+ };
1044
+ type PartnerHeartbeatTelemetry = {
1045
+ agentStatus?: string;
1046
+ agentVersion?: string;
1047
+ android_api_level?: number;
1048
+ bandwidthMbps?: number;
1049
+ brightness?: number;
1050
+ connectionType?: string;
1051
+ desugaring_enabled?: boolean;
1052
+ downlinkMbps?: number;
1053
+ ima_integration?: "android_native" | "html5_webview" | "disabled" | "unknown";
1054
+ ima_sdk_version?: string;
1055
+ ima_support_reason?: string;
1056
+ ima_supported?: boolean;
1057
+ inputSource?: string;
1058
+ last_ima_error_code?: number;
1059
+ last_vast_error_code?: number;
1060
+ last_vast_request_at?: string;
1061
+ last_vast_response_at?: string;
1062
+ latencyRtt?: number;
1063
+ make?: string;
1064
+ model?: string;
1065
+ muted?: boolean;
1066
+ networkConnectionType?: string;
1067
+ networkEffectiveType?: string;
1068
+ networkStrengthDbm?: number;
1069
+ os?: string;
1070
+ osVersion?: string;
1071
+ osv?: string;
1072
+ powerState?: "on" | "standby" | "off" | "unknown";
1073
+ proof_of_play_enabled?: boolean;
1074
+ rtt?: number;
1075
+ saveData?: boolean;
1076
+ temperatureC?: number;
1077
+ uptimeSeconds?: number;
1078
+ volume?: number;
1079
+ webview_chromium_major?: number;
1080
+ [key: string]: unknown;
1081
+ };
1082
+ /**
1083
+ * Partner-safe subset of device telemetry. Strips MDM compliance,
1084
+ * Vertex embeddings, identity-correction internals, partner identifiers,
1085
+ * and Mongo `_id` so partners only see what they need to decide
1086
+ * whether a device is healthy enough to receive ads.
1087
+ *
1088
+ */
1089
+ type PartnerSafeHeartbeatTelemetry = {
1090
+ agentStatus?: string | null;
1091
+ agentVersion?: string | null;
1092
+ bandwidthMbps?: number | null;
1093
+ brightness?: number | null;
1094
+ connectionType?: string | null;
1095
+ consecutiveAdFailures?: number | null;
1096
+ effectiveType?: string | null;
1097
+ latencyRtt?: number | null;
1098
+ make?: string | null;
1099
+ model?: string | null;
1100
+ muted?: boolean | null;
1101
+ networkStrengthDbm?: number | null;
1102
+ onlineStatus?: "online" | "offline" | "standby" | "unknown" | null;
1103
+ os?: string | null;
1104
+ osv?: string | null;
1105
+ powerState?: string | null;
1106
+ temperatureC?: number | null;
1107
+ ua?: string | null;
1108
+ uptimeSeconds?: number | null;
1109
+ visibilityState?: string | null;
1110
+ volume?: number | null;
1111
+ [key: string]: unknown;
1112
+ };
1113
+ type SsdpDeviceInfo = {
1114
+ friendlyName?: string | null;
1115
+ location: string;
1116
+ manufacturer?: string | null;
1117
+ modelName?: string | null;
1118
+ server?: string | null;
1119
+ st: string;
1120
+ udn?: string | null;
1121
+ [key: string]: unknown;
1122
+ };
1123
+ type WifiEnvironmentSnapshot = {
1124
+ channelCongestionRatio?: number | null;
1125
+ connectedChannelWidthMhz?: number | null;
1126
+ connectedFrequencyMhz?: number | null;
1127
+ connectedLinkSpeedMbps?: number | null;
1128
+ connectedSignalDbm?: number | null;
1129
+ frequencyBand?: string | null;
1130
+ medianSignalDbm?: number | null;
1131
+ networkCount?: number | null;
1132
+ rssiVariance?: number | null;
1133
+ scanTimestampMs?: number | null;
1134
+ signalSpreadDbm?: number | null;
1135
+ uniqueBssidCount?: number | null;
1136
+ [key: string]: unknown;
1137
+ } | null;
1138
+ type WifiScanResult = {
1139
+ channelWidthMhz?: number | null;
1140
+ frequencyMhz: number;
1141
+ rawBssid: string;
1142
+ signalStrengthDbm: number;
1143
+ [key: string]: unknown;
1144
+ };
1145
+ /**
1146
+ * Read live device heartbeat state
1147
+ * GET /device/{deviceId}/heartbeat
1148
+ */
1149
+ interface getDeviceHeartbeatOperation {
1150
+ readonly path: "/device/{deviceId}/heartbeat";
1151
+ readonly method: "GET";
1152
+ request: never;
1153
+ response: PartnerHeartbeatQueryResponse;
1154
+ }
1155
+ /**
1156
+ * Device heartbeat
1157
+ * POST /device/{deviceId}/heartbeat
1158
+ */
1159
+ interface heartbeatOperation {
1160
+ readonly path: "/device/{deviceId}/heartbeat";
1161
+ readonly method: "POST";
1162
+ request: PartnerHeartbeatRequest | PartnerDeviceHeartbeatBody;
1163
+ response: PartnerHeartbeatResponse;
1164
+ }
1165
+ declare const generatedTypes: {
1166
+ readonly schemaCount: 71;
1167
+ readonly operationCount: 175;
1168
+ readonly schemas: readonly ["Ad", "AdSettings", "AudienceAnalyticsResponse", "AudienceAttentionPrediction", "AudienceExportResponse", "AudienceLoyaltyFeaturesRow", "AudienceMetricsResponse", "AudienceSegment", "AudienceSocialAttention", "BatchResult", "BleScanResultData", "ChangelogEntry", "ChangelogResponse", "ContentPreferencesInput", "ContentPreferencesResponse", "ContentPreset", "DashboardResponse", "DataExportSummaryResponse", "DemographicsResponse", "Device", "DeviceCapabilityPayload", "DeviceSummary", "DisplaySettingsInput", "DisplaySettingsResponse", "EarningsBreakdownResponse", "EarningsResponse", "Error", "HeaderBiddingSettings", "HttpProbeResult", "MdnsNetworkDevice", "Pagination", "Partner", "PartnerAdDeliveryProfile", "PartnerDefaultStream", "PartnerDefaultStreamCreate", "PartnerDefaultStreamUpdate", "PartnerDeviceHeartbeatBody", "PartnerHeartbeatCommand", "PartnerHeartbeatData", "PartnerHeartbeatMeasurementMetadata", "PartnerHeartbeatQueryData", "PartnerHeartbeatQueryResponse", "PartnerHeartbeatRequest", "PartnerHeartbeatResponse", "PartnerHeartbeatTelemetry", "PartnerLBarContent", "PartnerLBarDisplayPreferences", "PartnerLBarSettings", "PartnerSafeHeartbeatTelemetry", "PartnerSelfPromoAd", "PartnerSelfPromoCreate", "PartnerSelfPromoPlacement", "PartnerStats", "PayoutResponse", "PlaygroundResult", "PlaygroundValidationError", "ProgrammaticSettingsInput", "ProgrammaticSettingsResponse", "RequestMetadataResponse", "RolePermissions", "SDKConfig", "ScreenAnalyticsResponse", "SsdpDeviceInfo", "TeamInviteResponse", "TeamMember", "Transaction", "Webhook", "WebhookDelivery", "WebhookEvent", "WifiEnvironmentSnapshot", "WifiScanResult"];
1169
+ readonly operations: readonly ["listPartnerSelfPromoAds", "createPartnerSelfPromoAd", "listPartnerSelfPromoPlacements", "schedulePartnerSelfPromo", "createPartnerSelfPromoUpload", "disableSelfPromoAd", "registerAgent", "getAnalytics", "getAudienceContinuity", "getAudienceProfile", "getBleSummary", "getContentPerformance", "searchCreativeCatalog", "getCreativeScenes", "getCrossScreenFlow", "getPartnerAnalyticsDashboard", "getDeviceSuiteSignature", "exportPartnerAnalytics", "exportPartnerAdsByDay", "getFleetHourly", "getHaloFunnel", "getLoyaltyClock", "getNetworkSummary", "getNetworkTrend", "getProximitySummary", "getRevenueAttentionCorrelation", "getSceneFeed", "getSceneIntelligence", "rotateApiKey", "getAudienceAnalytics", "exportAudienceData", "getAudienceHeatmap", "getLiveAudience", "getLookalikeScreens", "predictScreenAudience", "getResolvedHouseholdReach", "listAudienceSegments", "createAudienceSegment", "deleteAudienceSegment", "getAudienceSegment", "updateAudienceSegment", "matchAudienceSegment", "estimateSegmentReach", "generateSegmentVastTag", "getAudienceStats", "cancelBillingSubscription", "purchaseCredits", "createCreditCheckout", "listBillingPlans", "setupBilling", "createBillingSubscription", "getBillingSubscription", "getBillingUsage", "getUsageSummary", "stripeWebhookCallback", "getConnectDashboard", "getConnectEarningsChart", "getConnectScreenHealth", "listContentPresets", "getContentPreset", "getDashboard", "exportProximityGraphEdges", "getDataExportSummary", "exportDataset", "getGeohashAudiencePanel", "registerDevice", "deleteDevice", "getDevice", "updateDevice", "getAdsForDevice", "ackDeviceCommand", "getDeviceHeartbeat", "heartbeat", "recordProgrammaticEvent", "listDevices", "registerDevicesBatch", "batchUpdateDeviceOrientation", "partnerDocsBrowser", "getEarnings", "getEarningsBreakdown", "requestPayout", "getTransactions", "getActiveSSEConnections", "subscribeToEvents", "getFleetAnalytics", "pushFleetCommand", "getFleetOverview", "updateFleetSettings", "recordImpressionGet", "recordImpressionPost", "recordImpressionsBatch", "getPartnerInfo", "listIntentCategories", "getIntentCategory", "getIntentPricing", "getMeasurementMethodology", "getNetworkConfig", "patchNetworkConfig", "updateNetworkConfig", "getNetworkTrends", "partnerPing", "partnerPingAuth", "getPricing", "quickStart", "registerPartner", "generateSandboxEvent", "resetSandbox", "createSandboxScreen", "getSandboxStatus", "getScreenAudienceSegments", "batchUpdateContentPreferences", "batchUpdateDisplaySettings", "batchUpdateProgrammaticSettings", "resolvePartnerScreen", "getScreenAnalytics", "getPartnerScreenAtmosphere", "getPartnerScreenIntelligence", "getPartnerScreenTasteProfile", "getPartnerScreenTraffic", "getPartnerScreenVAS", "applyContentPreset", "getAudienceMetrics", "getContentPreferences", "patchContentPreferences", "updateContentPreferences", "listPartnerDefaultStreams", "createPartnerDefaultStream", "createPartnerDefaultStreamImages", "reorderPartnerDefaultStreams", "createPartnerDefaultStreamUpload", "deletePartnerDefaultStream", "updatePartnerDefaultStream", "getScreenDemographics", "getDisplaySettings", "patchDisplaySettings", "updateDisplaySettings", "getPartnerLBarSettings", "updatePartnerLBarSettings", "updatePartnerLBarLiveUpdates", "getProgrammaticSettings", "patchProgrammaticSettings", "updateProgrammaticSettings", "createStripeConnectAccount", "getStripeLoginLink", "getStripeOnboardingLink", "requestStripePayout", "getStripePayoutHistory", "getStripeAccountStatus", "handleStripeWebhook", "listTeamMembers", "acceptInvitation", "inviteTeamMember", "getInvitationByToken", "resendInvitation", "removeTeamMember", "changeTeamMemberRole", "getTrackingPublicKey", "recordTrackingBatch", "getUsageSummary__get__usage", "getUsageDashboard", "getRateLimitStatus", "queryChangelog", "playgroundDryRun", "getRequestMetadata", "getVastConfig", "getVenuesNearby", "getVenueAtmosphere", "getVenueTraffic", "getVenueIntelligence", "listWebhooks", "createWebhook", "deleteWebhook", "updateWebhook", "getWebhookDeliveries", "testWebhook"];
1170
+ };
1171
+ type GeneratedSchemaName = (typeof generatedTypes.schemas)[number];
1172
+ type GeneratedOperationName = (typeof generatedTypes.operations)[number];
645
1173
 
646
- export { AnalyticsClient, type AnalyticsData, type ApiErrorType, AudienceClient, type AudienceData, BillingClient, type BillingInfo, type ClientOptions, DataClient, type Device, DevicesClient, EarningsClient, type EarningsData, type ErrorDetail, type ErrorEntry, type ErrorResponseBody, ErrorsClient, FleetClient, type FleetCommand, type Impression, ImpressionsClient, type ListResponse, type RequestOptions, type Screen, ScreensClient, TrillboardsClient, TrillboardsError, type TrillboardsErrorOptions, VERSION, type Webhook, type WebhookEvent, Webhooks, WebhooksClient, constructEvent, generatedTypes };
1174
+ export { AnalyticsClient, type AnalyticsData, type ApiErrorType, AudienceClient, type AudienceData, BillingClient, type BillingInfo, type BleScanResultData, type ClientOptions, type ConstructEventOptions, DataClient, type Device, type DeviceCapabilityPayload, DevicesClient, EarningsClient, type EarningsData, type ErrorDetail, type ErrorEntry, type ErrorResponseBody, ErrorsClient, FleetClient, type FleetCommand, type GeneratedOperationName, type GeneratedSchemaName, type HttpProbeResult, type Impression, ImpressionsClient, type ListResponse, type MdnsNetworkDevice, type ParsedSignatureHeader, type PartnerAdDeliveryProfile, type PartnerDeviceHeartbeatBody, type PartnerHeartbeatMeasurementMetadata, type PartnerHeartbeatQueryData, type PartnerHeartbeatQueryResponse, type PartnerHeartbeatRequest, type PartnerHeartbeatResponse, type PartnerSafeHeartbeatTelemetry, type RequestOptions, type RetryOptions, type Screen, ScreensClient, type SsdpDeviceInfo, TrillboardsClient, TrillboardsError, type TrillboardsErrorOptions, VERSION, type Webhook, type WebhookEvent, type WebhookHeaders, Webhooks, WebhooksClient, type WifiEnvironmentSnapshot, type WifiScanResult, constructEvent, constructEventLegacy, generatedTypes, type getDeviceHeartbeatOperation, type heartbeatOperation, parseSignatureHeader, retryWithBackoff };