datadog_api/
models.rs

1use serde::{Deserialize, Serialize};
2use std::collections::HashMap;
3
4// Common types
5pub type Tags = Vec<String>;
6pub type JsonValue = serde_json::Value;
7
8// ============================================================================
9// DASHBOARD WIDGETS
10// ============================================================================
11
12/// Common widget definition structure
13#[derive(Debug, Clone, Serialize, Deserialize)]
14pub struct Widget {
15    /// Widget definition containing type-specific configuration
16    pub definition: WidgetDefinition,
17    /// Widget layout (for free-form dashboards)
18    #[serde(skip_serializing_if = "Option::is_none")]
19    pub layout: Option<WidgetLayout>,
20    /// Widget ID (set by Datadog)
21    #[serde(skip_serializing_if = "Option::is_none")]
22    pub id: Option<i64>,
23}
24
25/// Widget layout for free-form dashboards
26#[derive(Debug, Clone, Serialize, Deserialize)]
27pub struct WidgetLayout {
28    pub x: i64,
29    pub y: i64,
30    pub width: i64,
31    pub height: i64,
32}
33
34/// Widget definition - uses tagged enum for type safety
35#[derive(Debug, Clone, Serialize, Deserialize)]
36#[serde(tag = "type", rename_all = "snake_case")]
37pub enum WidgetDefinition {
38    /// Timeseries graph widget
39    Timeseries(TimeseriesDefinition),
40    /// Single value query widget
41    QueryValue(QueryValueDefinition),
42    /// Top list widget
43    Toplist(ToplistDefinition),
44    /// Table widget
45    QueryTable(QueryTableDefinition),
46    /// Heatmap widget
47    Heatmap(HeatmapDefinition),
48    /// Note/text widget
49    Note(NoteDefinition),
50    /// Group widget (contains other widgets)
51    Group(GroupDefinition),
52    /// Fallback for unsupported widget types
53    #[serde(other, rename = "unknown")]
54    Unknown,
55}
56
57/// Timeseries widget definition
58#[derive(Debug, Clone, Serialize, Deserialize)]
59pub struct TimeseriesDefinition {
60    pub requests: Vec<TimeseriesRequest>,
61    #[serde(skip_serializing_if = "Option::is_none")]
62    pub title: Option<String>,
63    #[serde(skip_serializing_if = "Option::is_none")]
64    pub show_legend: Option<bool>,
65    #[serde(skip_serializing_if = "Option::is_none")]
66    pub legend_size: Option<String>,
67}
68
69/// Request for timeseries data
70#[derive(Debug, Clone, Serialize, Deserialize)]
71pub struct TimeseriesRequest {
72    #[serde(skip_serializing_if = "Option::is_none")]
73    pub q: Option<String>,
74    #[serde(skip_serializing_if = "Option::is_none")]
75    pub queries: Option<Vec<JsonValue>>,
76    #[serde(skip_serializing_if = "Option::is_none")]
77    pub formulas: Option<Vec<JsonValue>>,
78    #[serde(skip_serializing_if = "Option::is_none")]
79    pub display_type: Option<String>,
80    #[serde(skip_serializing_if = "Option::is_none")]
81    pub style: Option<JsonValue>,
82}
83
84/// Query value widget definition
85#[derive(Debug, Clone, Serialize, Deserialize)]
86pub struct QueryValueDefinition {
87    pub requests: Vec<QueryValueRequest>,
88    #[serde(skip_serializing_if = "Option::is_none")]
89    pub title: Option<String>,
90    #[serde(skip_serializing_if = "Option::is_none")]
91    pub precision: Option<i32>,
92    #[serde(skip_serializing_if = "Option::is_none")]
93    pub autoscale: Option<bool>,
94}
95
96/// Request for query value
97#[derive(Debug, Clone, Serialize, Deserialize)]
98pub struct QueryValueRequest {
99    #[serde(skip_serializing_if = "Option::is_none")]
100    pub q: Option<String>,
101    #[serde(skip_serializing_if = "Option::is_none")]
102    pub queries: Option<Vec<JsonValue>>,
103    #[serde(skip_serializing_if = "Option::is_none")]
104    pub formulas: Option<Vec<JsonValue>>,
105    #[serde(skip_serializing_if = "Option::is_none")]
106    pub aggregator: Option<String>,
107}
108
109/// Toplist widget definition
110#[derive(Debug, Clone, Serialize, Deserialize)]
111pub struct ToplistDefinition {
112    pub requests: Vec<ToplistRequest>,
113    #[serde(skip_serializing_if = "Option::is_none")]
114    pub title: Option<String>,
115}
116
117/// Request for toplist
118#[derive(Debug, Clone, Serialize, Deserialize)]
119pub struct ToplistRequest {
120    #[serde(skip_serializing_if = "Option::is_none")]
121    pub q: Option<String>,
122    #[serde(skip_serializing_if = "Option::is_none")]
123    pub queries: Option<Vec<JsonValue>>,
124    #[serde(skip_serializing_if = "Option::is_none")]
125    pub formulas: Option<Vec<JsonValue>>,
126}
127
128/// Query table widget definition
129#[derive(Debug, Clone, Serialize, Deserialize)]
130pub struct QueryTableDefinition {
131    pub requests: Vec<QueryTableRequest>,
132    #[serde(skip_serializing_if = "Option::is_none")]
133    pub title: Option<String>,
134}
135
136/// Request for query table
137#[derive(Debug, Clone, Serialize, Deserialize)]
138pub struct QueryTableRequest {
139    #[serde(skip_serializing_if = "Option::is_none")]
140    pub q: Option<String>,
141    #[serde(skip_serializing_if = "Option::is_none")]
142    pub queries: Option<Vec<JsonValue>>,
143    #[serde(skip_serializing_if = "Option::is_none")]
144    pub formulas: Option<Vec<JsonValue>>,
145}
146
147/// Heatmap widget definition
148#[derive(Debug, Clone, Serialize, Deserialize)]
149pub struct HeatmapDefinition {
150    pub requests: Vec<HeatmapRequest>,
151    #[serde(skip_serializing_if = "Option::is_none")]
152    pub title: Option<String>,
153}
154
155/// Request for heatmap
156#[derive(Debug, Clone, Serialize, Deserialize)]
157pub struct HeatmapRequest {
158    #[serde(skip_serializing_if = "Option::is_none")]
159    pub q: Option<String>,
160    #[serde(skip_serializing_if = "Option::is_none")]
161    pub style: Option<JsonValue>,
162}
163
164/// Note/text widget definition
165#[derive(Debug, Clone, Serialize, Deserialize)]
166pub struct NoteDefinition {
167    pub content: String,
168    #[serde(skip_serializing_if = "Option::is_none")]
169    pub background_color: Option<String>,
170    #[serde(skip_serializing_if = "Option::is_none")]
171    pub font_size: Option<String>,
172    #[serde(skip_serializing_if = "Option::is_none")]
173    pub text_align: Option<String>,
174    #[serde(skip_serializing_if = "Option::is_none")]
175    pub show_tick: Option<bool>,
176    #[serde(skip_serializing_if = "Option::is_none")]
177    pub tick_pos: Option<String>,
178    #[serde(skip_serializing_if = "Option::is_none")]
179    pub tick_edge: Option<String>,
180}
181
182/// Group widget definition (contains nested widgets)
183#[derive(Debug, Clone, Serialize, Deserialize)]
184pub struct GroupDefinition {
185    pub layout_type: String,
186    pub widgets: Vec<Widget>,
187    #[serde(skip_serializing_if = "Option::is_none")]
188    pub title: Option<String>,
189}
190
191// Metrics
192#[derive(Debug, Clone, Serialize, Deserialize)]
193pub struct MetricsQueryResponse {
194    pub series: Option<Vec<MetricSeries>>,
195    pub status: Option<String>,
196}
197
198#[derive(Debug, Clone, Serialize, Deserialize)]
199pub struct MetricSeries {
200    pub metric: Option<String>,
201    pub pointlist: Option<Vec<Vec<serde_json::Value>>>,
202    pub scope: Option<String>,
203    pub display_name: Option<String>,
204    pub unit: Option<Vec<MetricUnit>>,
205}
206
207#[derive(Debug, Clone, Serialize, Deserialize)]
208pub struct MetricUnit {
209    pub family: Option<String>,
210    pub name: Option<String>,
211    pub plural: Option<String>,
212    pub scale_factor: Option<f64>,
213    pub short_name: Option<String>,
214}
215
216#[derive(Debug, Clone, Serialize, Deserialize)]
217pub struct MetricsListResponse {
218    pub metrics: Option<Vec<String>>,
219}
220
221#[derive(Debug, Clone, Serialize, Deserialize)]
222pub struct MetricMetadata {
223    pub description: Option<String>,
224    pub short_name: Option<String>,
225    #[serde(rename = "type")]
226    pub metric_type: Option<String>,
227    pub unit: Option<String>,
228    pub per_unit: Option<String>,
229    pub statsd_interval: Option<i64>,
230}
231
232// Monitors
233#[derive(Debug, Clone, Serialize, Deserialize)]
234pub struct Monitor {
235    pub id: Option<i64>,
236    pub name: Option<String>,
237    #[serde(rename = "type")]
238    pub monitor_type: Option<String>,
239    pub query: Option<String>,
240    pub message: Option<String>,
241    pub tags: Option<Tags>,
242    pub options: Option<MonitorOptions>,
243    pub overall_state: Option<String>,
244    pub created: Option<String>,
245    pub modified: Option<String>,
246    pub creator: Option<Creator>,
247}
248
249#[derive(Debug, Clone, Serialize, Deserialize)]
250pub struct MonitorOptions {
251    pub thresholds: Option<MonitorThresholds>,
252    pub notify_no_data: Option<bool>,
253    pub no_data_timeframe: Option<i64>,
254    pub renotify_interval: Option<i64>,
255    pub escalation_message: Option<String>,
256}
257
258#[derive(Debug, Clone, Serialize, Deserialize)]
259pub struct MonitorThresholds {
260    pub critical: Option<f64>,
261    pub warning: Option<f64>,
262    pub ok: Option<f64>,
263}
264
265#[derive(Debug, Clone, Serialize, Deserialize)]
266pub struct Creator {
267    pub email: Option<String>,
268    pub handle: Option<String>,
269    pub name: Option<String>,
270}
271
272#[derive(Debug, Clone, Serialize, Deserialize)]
273pub struct MonitorCreateRequest {
274    pub name: String,
275    #[serde(rename = "type")]
276    pub monitor_type: String,
277    pub query: String,
278    pub message: Option<String>,
279    pub tags: Option<Tags>,
280    pub options: Option<MonitorOptions>,
281}
282
283#[derive(Debug, Clone, Serialize, Deserialize)]
284pub struct MonitorUpdateRequest {
285    pub name: Option<String>,
286    pub query: Option<String>,
287    pub message: Option<String>,
288    pub tags: Option<Tags>,
289    pub options: Option<MonitorOptions>,
290}
291
292#[derive(Debug, Clone, Serialize, Deserialize)]
293pub struct MonitorSearchResponse {
294    pub counts: Option<MonitorSearchCounts>,
295    pub metadata: Option<MonitorSearchMetadata>,
296    pub monitors: Option<Vec<MonitorSearchResult>>,
297}
298
299#[derive(Debug, Clone, Serialize, Deserialize)]
300pub struct MonitorSearchCounts {
301    pub muted: Option<Vec<MonitorSearchFacet>>,
302    pub status: Option<Vec<MonitorSearchFacet>>,
303    #[serde(rename = "tag")]
304    pub tags: Option<Vec<MonitorSearchFacet>>,
305    #[serde(rename = "type")]
306    pub types: Option<Vec<MonitorSearchFacet>>,
307}
308
309#[derive(Debug, Clone, Serialize, Deserialize)]
310pub struct MonitorSearchFacet {
311    pub count: Option<i64>,
312    pub name: Option<JsonValue>,
313}
314
315#[derive(Debug, Clone, Serialize, Deserialize)]
316pub struct MonitorSearchMetadata {
317    pub page: Option<i64>,
318    pub page_count: Option<i64>,
319    pub per_page: Option<i64>,
320    pub total_count: Option<i64>,
321}
322
323#[derive(Debug, Clone, Serialize, Deserialize)]
324pub struct MonitorSearchResult {
325    pub classification: Option<String>,
326    pub creator: Option<Creator>,
327    pub id: Option<i64>,
328    pub last_triggered_ts: Option<i64>,
329    pub metrics: Option<Vec<String>>,
330    pub name: Option<String>,
331    pub notifications: Option<Vec<MonitorSearchNotification>>,
332    pub org_id: Option<i64>,
333    pub quality_issues: Option<Vec<String>>,
334    pub query: Option<String>,
335    pub scopes: Option<Vec<String>>,
336    pub status: Option<String>,
337    pub tags: Option<Vec<String>>,
338    #[serde(rename = "type")]
339    pub monitor_type: Option<String>,
340}
341
342#[derive(Debug, Clone, Serialize, Deserialize)]
343pub struct MonitorSearchNotification {
344    pub handle: Option<String>,
345    pub name: Option<String>,
346}
347
348// Dashboards
349#[derive(Debug, Clone, Serialize, Deserialize)]
350pub struct DashboardListResponse {
351    pub dashboards: Option<Vec<DashboardSummary>>,
352}
353
354#[derive(Debug, Clone, Serialize, Deserialize)]
355pub struct DashboardSummary {
356    pub id: Option<String>,
357    pub title: Option<String>,
358    pub description: Option<String>,
359    pub author_handle: Option<String>,
360    pub created_at: Option<String>,
361    pub modified_at: Option<String>,
362    pub url: Option<String>,
363    pub layout_type: Option<String>,
364}
365
366#[derive(Debug, Clone, Serialize, Deserialize)]
367pub struct Dashboard {
368    pub id: Option<String>,
369    pub title: Option<String>,
370    pub description: Option<String>,
371    pub widgets: Option<Vec<Widget>>,
372    pub layout_type: Option<String>,
373    pub is_read_only: Option<bool>,
374    pub notify_list: Option<Vec<String>>,
375    pub template_variables: Option<Vec<TemplateVariable>>,
376}
377
378/// Dashboard template variable
379#[derive(Debug, Clone, Serialize, Deserialize)]
380pub struct TemplateVariable {
381    pub name: String,
382    #[serde(skip_serializing_if = "Option::is_none")]
383    pub prefix: Option<String>,
384    #[serde(skip_serializing_if = "Option::is_none")]
385    pub default: Option<String>,
386    #[serde(skip_serializing_if = "Option::is_none")]
387    pub defaults: Option<Vec<String>>,
388    #[serde(skip_serializing_if = "Option::is_none")]
389    pub available_values: Option<Vec<String>>,
390}
391
392// Logs
393#[derive(Debug, Clone, Serialize, Deserialize)]
394pub struct LogsSearchRequest {
395    pub filter: LogsFilter,
396    pub page: Option<LogsPage>,
397    pub sort: Option<String>,
398}
399
400#[derive(Debug, Clone, Serialize, Deserialize)]
401pub struct LogsFilter {
402    pub query: String,
403    pub from: String,
404    pub to: String,
405}
406
407#[derive(Debug, Clone, Serialize, Deserialize)]
408pub struct LogsPage {
409    pub limit: Option<i32>,
410    pub cursor: Option<String>,
411}
412
413#[derive(Debug, Clone, Serialize, Deserialize)]
414pub struct LogsSearchResponse {
415    pub data: Option<Vec<LogEntry>>,
416    pub meta: Option<LogsMeta>,
417}
418
419#[derive(Debug, Clone, Serialize, Deserialize)]
420pub struct LogEntry {
421    pub id: Option<String>,
422    pub attributes: Option<JsonValue>,
423}
424
425#[derive(Debug, Clone, Serialize, Deserialize)]
426pub struct LogsMeta {
427    pub page: Option<LogsPageInfo>,
428}
429
430#[derive(Debug, Clone, Serialize, Deserialize)]
431pub struct LogsPageInfo {
432    pub after: Option<String>,
433}
434
435// Events
436#[derive(Debug, Clone, Serialize, Deserialize)]
437pub struct EventsResponse {
438    pub events: Option<Vec<Event>>,
439    pub status: Option<String>,
440}
441
442#[derive(Debug, Clone, Serialize, Deserialize)]
443pub struct Event {
444    pub id: Option<i64>,
445    pub id_str: Option<String>,
446    pub title: Option<String>,
447    pub text: Option<String>,
448    pub date_happened: Option<i64>,
449    pub device_name: Option<String>,
450    pub host: Option<String>,
451    pub tags: Option<Tags>,
452    pub priority: Option<String>,
453    pub alert_type: Option<String>,
454    pub source_type_name: Option<String>,
455    pub payload: Option<String>,
456    pub url: Option<String>,
457}
458
459#[derive(Debug, Clone, Serialize, Deserialize)]
460pub struct EventCreateRequest {
461    pub title: String,
462    pub text: String,
463    #[serde(skip_serializing_if = "Option::is_none")]
464    pub aggregation_key: Option<String>,
465    #[serde(skip_serializing_if = "Option::is_none")]
466    pub alert_type: Option<String>,
467    #[serde(skip_serializing_if = "Option::is_none")]
468    pub date_happened: Option<i64>,
469    #[serde(skip_serializing_if = "Option::is_none")]
470    pub device_name: Option<String>,
471    #[serde(skip_serializing_if = "Option::is_none")]
472    pub host: Option<String>,
473    #[serde(skip_serializing_if = "Option::is_none")]
474    pub priority: Option<String>,
475    #[serde(skip_serializing_if = "Option::is_none")]
476    pub related_event_id: Option<i64>,
477    #[serde(skip_serializing_if = "Option::is_none")]
478    pub source_type_name: Option<String>,
479    #[serde(skip_serializing_if = "Option::is_none")]
480    pub tags: Option<Tags>,
481}
482
483#[derive(Debug, Clone, Serialize, Deserialize)]
484pub struct EventResponse {
485    pub event: Option<Event>,
486    pub status: Option<String>,
487}
488
489// Infrastructure
490#[derive(Debug, Clone, Serialize, Deserialize)]
491pub struct HostsResponse {
492    pub host_list: Option<Vec<Host>>,
493    pub total_matching: Option<i64>,
494    pub total_returned: Option<i64>,
495}
496
497#[derive(Debug, Clone, Serialize, Deserialize)]
498pub struct Host {
499    pub id: Option<i64>,
500    pub name: Option<String>,
501    pub up: Option<bool>,
502    pub last_reported_time: Option<i64>,
503    pub tags_by_source: Option<HashMap<String, Tags>>,
504    pub meta: Option<HostMeta>,
505}
506
507#[derive(Debug, Clone, Serialize, Deserialize)]
508pub struct HostMeta {
509    pub agent_version: Option<String>,
510    pub cpu_cores: Option<i64>,
511    pub platform: Option<String>,
512}
513
514#[derive(Debug, Clone, Serialize, Deserialize)]
515pub struct TagsResponse {
516    pub tags: Option<HashMap<String, Tags>>,
517}
518
519// Downtimes
520#[derive(Debug, Clone, Serialize, Deserialize)]
521pub struct Downtime {
522    pub id: Option<i64>,
523    pub scope: Option<Tags>,
524    pub start: Option<i64>,
525    pub end: Option<i64>,
526    pub message: Option<String>,
527    pub active: Option<bool>,
528    pub canceled: Option<i64>,
529}
530
531#[derive(Debug, Clone, Serialize, Deserialize)]
532pub struct DowntimeCreateRequest {
533    pub scope: Tags,
534    pub start: Option<i64>,
535    pub end: Option<i64>,
536    pub message: Option<String>,
537}
538
539// Synthetics
540#[derive(Debug, Clone, Serialize, Deserialize)]
541pub struct SyntheticsTestsResponse {
542    pub tests: Option<Vec<SyntheticsTest>>,
543}
544
545#[derive(Debug, Clone, Serialize, Deserialize)]
546pub struct SyntheticsTest {
547    pub public_id: Option<String>,
548    pub name: Option<String>,
549    #[serde(rename = "type")]
550    pub test_type: Option<String>,
551    pub status: Option<String>,
552    pub tags: Option<Tags>,
553}
554
555#[derive(Debug, Clone, Serialize, Deserialize)]
556pub struct SyntheticsLocation {
557    pub id: String,
558    pub name: String,
559    pub is_private: Option<bool>,
560    pub region: Option<SyntheticsRegion>,
561}
562
563#[derive(Debug, Clone, Serialize, Deserialize)]
564pub struct SyntheticsRegion {
565    pub name: String,
566}
567
568#[derive(Debug, Clone, Serialize, Deserialize)]
569pub struct SyntheticsLocationsResponse {
570    pub locations: Vec<SyntheticsLocation>,
571}
572
573#[derive(Debug, Clone, Serialize, Deserialize)]
574pub struct SyntheticsTestRequest {
575    pub method: String,
576    pub url: String,
577    #[serde(skip_serializing_if = "Option::is_none")]
578    pub timeout: Option<f64>,
579    #[serde(skip_serializing_if = "Option::is_none")]
580    pub headers: Option<std::collections::HashMap<String, String>>,
581    #[serde(skip_serializing_if = "Option::is_none")]
582    pub body: Option<String>,
583}
584
585#[derive(Debug, Clone, Serialize, Deserialize)]
586#[serde(rename_all = "camelCase")]
587pub enum SyntheticsAssertionType {
588    StatusCode,
589    ResponseTime,
590    Body,
591    Header,
592}
593
594#[derive(Debug, Clone, Serialize, Deserialize)]
595#[serde(rename_all = "camelCase")]
596pub enum SyntheticsAssertionOperator {
597    Is,
598    IsNot,
599    LessThan,
600    GreaterThan,
601    Contains,
602    DoesNotContain,
603}
604
605#[derive(Debug, Clone, Serialize, Deserialize)]
606pub struct SyntheticsAssertion {
607    #[serde(rename = "type")]
608    pub assertion_type: SyntheticsAssertionType,
609    pub operator: SyntheticsAssertionOperator,
610    pub target: serde_json::Value,
611}
612
613#[derive(Debug, Clone, Serialize, Deserialize)]
614pub struct SyntheticsTestConfig {
615    pub request: SyntheticsTestRequest,
616    pub assertions: Vec<SyntheticsAssertion>,
617}
618
619#[derive(Debug, Clone, Serialize, Deserialize)]
620pub struct SyntheticsTestOptions {
621    pub tick_every: i32,
622    #[serde(skip_serializing_if = "Option::is_none")]
623    pub min_failure_duration: Option<i32>,
624    #[serde(skip_serializing_if = "Option::is_none")]
625    pub min_location_failed: Option<i32>,
626    #[serde(skip_serializing_if = "Option::is_none")]
627    pub retry: Option<SyntheticsRetry>,
628}
629
630#[derive(Debug, Clone, Serialize, Deserialize)]
631pub struct SyntheticsRetry {
632    pub count: i32,
633    pub interval: i32,
634}
635
636#[derive(Debug, Clone, Serialize, Deserialize)]
637#[serde(rename_all = "lowercase")]
638pub enum SyntheticsTestType {
639    Api,
640    Browser,
641}
642
643#[derive(Debug, Clone, Serialize, Deserialize)]
644#[serde(rename_all = "lowercase")]
645pub enum SyntheticsTestSubtype {
646    Http,
647    Ssl,
648    Tcp,
649    Dns,
650    Multi,
651    Grpc,
652}
653
654#[derive(Debug, Clone, Serialize, Deserialize)]
655pub struct SyntheticsTestCreateRequest {
656    pub name: String,
657    #[serde(rename = "type")]
658    pub test_type: SyntheticsTestType,
659    pub subtype: SyntheticsTestSubtype,
660    pub config: SyntheticsTestConfig,
661    pub options: SyntheticsTestOptions,
662    pub locations: Vec<String>,
663    #[serde(skip_serializing_if = "Option::is_none")]
664    pub message: Option<String>,
665    #[serde(skip_serializing_if = "Option::is_none")]
666    pub tags: Option<Vec<String>>,
667    #[serde(skip_serializing_if = "Option::is_none")]
668    pub status: Option<String>,
669}
670
671#[derive(Debug, Clone, Serialize, Deserialize)]
672pub struct SyntheticsTestResponse {
673    pub public_id: String,
674    pub name: String,
675    #[serde(rename = "type")]
676    pub test_type: SyntheticsTestType,
677    pub subtype: SyntheticsTestSubtype,
678    pub config: SyntheticsTestConfig,
679    pub options: SyntheticsTestOptions,
680    pub locations: Vec<String>,
681    #[serde(skip_serializing_if = "Option::is_none")]
682    pub message: Option<String>,
683    #[serde(skip_serializing_if = "Option::is_none")]
684    pub tags: Option<Vec<String>>,
685    pub status: String,
686}
687
688#[derive(Debug, Clone, Serialize, Deserialize)]
689pub struct SyntheticsTriggerRequest {
690    pub tests: Vec<SyntheticsTriggerTest>,
691}
692
693#[derive(Debug, Clone, Serialize, Deserialize)]
694pub struct SyntheticsTriggerTest {
695    pub public_id: String,
696}
697
698#[derive(Debug, Clone, Serialize, Deserialize)]
699pub struct SyntheticsTriggerResponse {
700    pub triggered_check_ids: Vec<String>,
701    pub results: Vec<SyntheticsTriggerResult>,
702}
703
704#[derive(Debug, Clone, Serialize, Deserialize)]
705pub struct SyntheticsTriggerResult {
706    pub public_id: String,
707    pub result_id: String,
708}
709
710#[derive(Debug, Clone, Serialize, Deserialize)]
711pub struct SyntheticsDeleteTestsRequest {
712    #[serde(skip_serializing_if = "Option::is_none")]
713    pub force_delete_dependencies: Option<bool>,
714    pub public_ids: Vec<String>,
715}
716
717#[derive(Debug, Clone, Serialize, Deserialize)]
718pub struct SyntheticsDeleteTestsResponse {
719    pub deleted_tests: Option<Vec<SyntheticsDeletedTest>>,
720}
721
722#[derive(Debug, Clone, Serialize, Deserialize)]
723pub struct SyntheticsDeletedTest {
724    pub deleted_at: Option<String>,
725    pub public_id: Option<String>,
726}
727
728// Security
729#[derive(Debug, Clone, Serialize, Deserialize)]
730pub struct SecurityRulesResponse {
731    pub data: Option<Vec<SecurityRule>>,
732}
733
734#[derive(Debug, Clone, Serialize, Deserialize)]
735pub struct SecurityRule {
736    pub id: Option<String>,
737    pub attributes: Option<SecurityRuleAttributes>,
738}
739
740#[derive(Debug, Clone, Serialize, Deserialize)]
741pub struct SecurityRuleAttributes {
742    pub name: Option<String>,
743    #[serde(rename = "isEnabled")]
744    pub is_enabled: Option<bool>,
745    pub message: Option<String>,
746}
747
748// Incidents
749#[derive(Debug, Clone, Serialize, Deserialize)]
750pub struct IncidentsResponse {
751    pub data: Option<Vec<Incident>>,
752    pub meta: Option<IncidentsMeta>,
753}
754
755#[derive(Debug, Clone, Serialize, Deserialize)]
756pub struct Incident {
757    pub id: Option<String>,
758    pub attributes: Option<IncidentAttributes>,
759}
760
761#[derive(Debug, Clone, Serialize, Deserialize)]
762pub struct IncidentAttributes {
763    pub title: Option<String>,
764    pub state: Option<String>,
765    pub created: Option<String>,
766    pub modified: Option<String>,
767}
768
769#[derive(Debug, Clone, Serialize, Deserialize)]
770pub struct IncidentsMeta {
771    pub pagination: Option<Pagination>,
772}
773
774#[derive(Debug, Clone, Serialize, Deserialize)]
775pub struct Pagination {
776    pub next_offset: Option<i64>,
777    pub size: Option<i64>,
778}
779
780// SLOs
781#[derive(Debug, Clone, Serialize, Deserialize)]
782pub struct SLOsResponse {
783    pub data: Option<Vec<SLO>>,
784}
785
786#[derive(Debug, Clone, Serialize, Deserialize)]
787pub struct SLO {
788    pub id: Option<String>,
789    pub name: Option<String>,
790    pub description: Option<String>,
791    pub tags: Option<Tags>,
792    pub thresholds: Option<Vec<SLOThreshold>>,
793}
794
795#[derive(Debug, Clone, Serialize, Deserialize)]
796pub struct SLOThreshold {
797    pub target: Option<f64>,
798    pub timeframe: Option<String>,
799    pub warning: Option<f64>,
800}
801
802// Notebooks
803#[derive(Debug, Clone, Serialize, Deserialize)]
804pub struct NotebooksResponse {
805    pub data: Option<Vec<Notebook>>,
806}
807
808#[derive(Debug, Clone, Serialize, Deserialize)]
809pub struct Notebook {
810    pub id: Option<i64>,
811    pub attributes: Option<NotebookAttributes>,
812}
813
814#[derive(Debug, Clone, Serialize, Deserialize)]
815pub struct NotebookAttributes {
816    pub name: Option<String>,
817    pub author: Option<Creator>,
818    pub cells: Option<Vec<JsonValue>>,
819    pub created: Option<String>,
820    pub modified: Option<String>,
821}
822
823// Teams
824#[derive(Debug, Clone, Serialize, Deserialize)]
825pub struct TeamsResponse {
826    pub data: Option<Vec<Team>>,
827}
828
829#[derive(Debug, Clone, Serialize, Deserialize)]
830pub struct Team {
831    pub id: Option<String>,
832    pub attributes: Option<TeamAttributes>,
833}
834
835#[derive(Debug, Clone, Serialize, Deserialize)]
836pub struct TeamAttributes {
837    pub name: Option<String>,
838    pub handle: Option<String>,
839}
840
841// Users
842#[derive(Debug, Clone, Serialize, Deserialize)]
843pub struct UsersResponse {
844    pub users: Option<Vec<User>>,
845}
846
847#[derive(Debug, Clone, Serialize, Deserialize)]
848pub struct User {
849    pub id: Option<String>,
850    pub name: Option<String>,
851    pub email: Option<String>,
852    pub handle: Option<String>,
853    pub verified: Option<bool>,
854}
855
856// APM/Traces
857/// A single span in a distributed trace
858#[derive(Debug, Clone, Serialize, Deserialize)]
859pub struct Span {
860    /// Span ID (unique identifier for this span)
861    pub span_id: u64,
862    /// Trace ID (shared across all spans in the trace)
863    pub trace_id: u64,
864    /// Parent span ID (0 if root span)
865    #[serde(default)]
866    pub parent_id: u64,
867    /// Service name
868    pub service: String,
869    /// Resource name (e.g., endpoint, SQL query)
870    pub resource: String,
871    /// Operation name (e.g., "web.request", "db.query")
872    pub name: String,
873    /// Start timestamp (nanoseconds since epoch)
874    pub start: i64,
875    /// Duration in nanoseconds
876    pub duration: i64,
877    /// Error flag (0 = no error, 1 = error)
878    #[serde(default)]
879    pub error: i32,
880    /// Key-value metadata
881    #[serde(default)]
882    pub meta: HashMap<String, String>,
883    /// Numeric metadata
884    #[serde(default)]
885    pub metrics: HashMap<String, f64>,
886    /// Span type (web, db, cache, etc.)
887    #[serde(rename = "type", skip_serializing_if = "Option::is_none")]
888    pub span_type: Option<String>,
889}
890
891/// Request to submit traces
892#[derive(Debug, Clone, Serialize, Deserialize)]
893pub struct TraceSubmitRequest {
894    /// Array of traces (each trace is an array of spans)
895    pub traces: Vec<Vec<Span>>,
896}
897
898/// Response from trace submission
899#[derive(Debug, Clone, Serialize, Deserialize)]
900pub struct TraceSubmitResponse {
901    /// Status message
902    pub status: Option<String>,
903}
904
905/// Query parameters for searching traces
906#[derive(Debug, Clone, Serialize, Deserialize)]
907pub struct TraceQuery {
908    /// Service name filter
909    #[serde(skip_serializing_if = "Option::is_none")]
910    pub service: Option<String>,
911    /// Operation name filter
912    #[serde(skip_serializing_if = "Option::is_none")]
913    pub operation: Option<String>,
914    /// Resource filter
915    #[serde(skip_serializing_if = "Option::is_none")]
916    pub resource: Option<String>,
917    /// Start time (seconds since epoch)
918    pub start: i64,
919    /// End time (seconds since epoch)
920    pub end: i64,
921    /// Maximum number of results
922    #[serde(skip_serializing_if = "Option::is_none")]
923    pub limit: Option<i32>,
924}
925
926/// A single trace (collection of spans)
927#[derive(Debug, Clone, Serialize, Deserialize)]
928pub struct Trace {
929    /// Trace ID
930    pub trace_id: String,
931    /// All spans in this trace
932    pub spans: Vec<Span>,
933    /// Start time
934    #[serde(skip_serializing_if = "Option::is_none")]
935    pub start: Option<i64>,
936    /// End time
937    #[serde(skip_serializing_if = "Option::is_none")]
938    pub end: Option<i64>,
939}
940
941/// Response from trace search
942#[derive(Debug, Clone, Serialize, Deserialize)]
943pub struct TraceSearchResponse {
944    /// Matching traces
945    pub data: Option<Vec<Trace>>,
946    /// Metadata about the search
947    #[serde(skip_serializing_if = "Option::is_none")]
948    pub meta: Option<HashMap<String, JsonValue>>,
949}
950
951/// Service performance statistics
952#[derive(Debug, Clone, Serialize, Deserialize)]
953pub struct ServiceStats {
954    /// Service name
955    pub service: String,
956    /// Statistics by endpoint/resource
957    pub stats: Vec<ResourceStats>,
958}
959
960/// Statistics for a specific resource
961#[derive(Debug, Clone, Serialize, Deserialize)]
962pub struct ResourceStats {
963    /// Resource name
964    pub resource: String,
965    /// Request count
966    pub hits: i64,
967    /// Error count
968    pub errors: i64,
969    /// Average duration (nanoseconds)
970    pub duration: f64,
971    /// P50 latency
972    #[serde(skip_serializing_if = "Option::is_none")]
973    pub p50: Option<f64>,
974    /// P95 latency
975    #[serde(skip_serializing_if = "Option::is_none")]
976    pub p95: Option<f64>,
977    /// P99 latency
978    #[serde(skip_serializing_if = "Option::is_none")]
979    pub p99: Option<f64>,
980}
981
982/// Service dependencies
983#[derive(Debug, Clone, Serialize, Deserialize)]
984pub struct ServiceDependencies {
985    /// Service name
986    pub service: String,
987    /// Calls made to other services
988    pub calls: Vec<ServiceCall>,
989}
990
991/// A call from one service to another
992#[derive(Debug, Clone, Serialize, Deserialize)]
993pub struct ServiceCall {
994    /// Target service name
995    pub service: String,
996    /// Call count
997    pub count: i64,
998    /// Average duration
999    pub avg_duration: f64,
1000    /// Error rate
1001    pub error_rate: f64,
1002}