# Analytics Query ## Query analytics summary `client.AnalyticsQuery.Summary(ctx, dataset, params) (*AnalyticsQuerySummaryResponse, error)` **post** `/accounts/{account_id}/analytics/query/{dataset}/summary` Returns aggregate summary stats for a dataset. Includes current-period and previous-period totals for trend comparison. ### Parameters - `dataset string` - `params AnalyticsQuerySummaryParams` - `AccountID param.Field[string]` Path param: Cloudflare account identifier. - `Filters param.Field[[]AnalyticsQuerySummaryParamsFilter]` Body param: Filters to apply before aggregating results. - `Name string` Specifies the column name to filter on. Requires a valid column for the target dataset (e.g. `country`, `allowed`, `appId`). - `Op string` Filter operator. Common values: `eq`, `neq`, `in`, `not_in`, `gt`, `lt`, `gte`, `lte`. - `Values []AnalyticsQuerySummaryParamsFiltersValueUnion` Values to match against. Type depends on the column. - `UnionString` - `UnionBool` - `UnionFloat` - `From param.Field[Time]` Body param: The start of the query time range (inclusive). RFC3339 format with timezone is required (e.g. `2024-11-05T00:00:00Z`). - `GroupBy param.Field[[]string]` Body param: Specifies the column names to group results by. Requires valid columns for the target dataset. - `Stats param.Field[[]string]` Body param: Specifies the stat names to include in results. Requires valid stats for the target dataset (e.g. `attemptsTotal`, `bytesTotal`). - `To param.Field[Time]` Body param: Specifies the end of the query time range (exclusive). Requires RFC3339 format with timezone. ### Returns - `type AnalyticsQuerySummaryResponse struct{…}` - `CurrentTotal []map[string, unknown]` Aggregated stats for the requested time range. - `PreviousTotal []map[string, unknown]` Aggregated stats for the equivalent preceding time range, for trend comparison. ### Example ```go package main import ( "context" "fmt" "time" "github.com/cloudflare/cloudflare-go" "github.com/cloudflare/cloudflare-go/option" ) func main() { client := cloudflare.NewClient( option.WithAPIToken("Sn3lZJTBX6kkg7OdcBUAxOO963GEIyGQqnFTOFYY"), ) response, err := client.AnalyticsQuery.Summary( context.TODO(), "access-logins", cloudflare.AnalyticsQuerySummaryParams{ AccountID: cloudflare.F("023e105f4ecef8ad9ca31a8372d0c353"), Filters: cloudflare.F([]cloudflare.AnalyticsQuerySummaryParamsFilter{}), From: cloudflare.F(time.Now()), GroupBy: cloudflare.F([]string{}), Stats: cloudflare.F([]string{"attemptsTotal"}), To: cloudflare.F(time.Now()), }, ) if err != nil { panic(err.Error()) } fmt.Printf("%+v\n", response.CurrentTotal) } ``` #### Response ```json { "errors": [], "messages": [ { "code": 1000, "message": "API in beta: expect breaking changes." } ], "result": { "currentTotal": [ { "attemptsTotal": 48291 } ], "previousTotal": [ { "attemptsTotal": 41033 } ] }, "success": true } ``` ## Query analytics timeseries `client.AnalyticsQuery.Timeseries(ctx, dataset, params) (*AnalyticsQueryTimeseriesResponse, error)` **post** `/accounts/{account_id}/analytics/query/{dataset}/timeseries` Returns time-bucketed analytics data for a dataset. Includes time slots, each containing the requested stats, group-by dimensions, and resolution-controlled bucket size (e.g. `hour`, `day`). ### Parameters - `dataset string` - `params AnalyticsQueryTimeseriesParams` - `AccountID param.Field[string]` Path param: Cloudflare account identifier. - `Filters param.Field[[]AnalyticsQueryTimeseriesParamsFilter]` Body param: Filters to apply before aggregating results. - `Name string` Specifies the column name to filter on. Requires a valid column for the target dataset (e.g. `country`, `allowed`, `appId`). - `Op string` Filter operator. Common values: `eq`, `neq`, `in`, `not_in`, `gt`, `lt`, `gte`, `lte`. - `Values []AnalyticsQueryTimeseriesParamsFiltersValueUnion` Values to match against. Type depends on the column. - `UnionString` - `UnionBool` - `UnionFloat` - `From param.Field[Time]` Body param: The start of the query time range (inclusive). RFC3339 format with timezone is required (e.g. `2024-11-05T00:00:00Z`). - `GroupBy param.Field[[]string]` Body param: Specifies the column names to group results by. Requires valid columns for the target dataset. - `Resolution param.Field[string]` Body param: Time bucket size for grouping results. Controls the granularity of the returned time slots. - `Stats param.Field[[]string]` Body param: Specifies the stat names to include in results. Requires valid stats for the target dataset (e.g. `attemptsTotal`, `bytesTotal`). - `To param.Field[Time]` Body param: Specifies the end of the query time range (exclusive). Requires RFC3339 format with timezone. ### Returns - `type AnalyticsQueryTimeseriesResponse struct{…}` - `Resolution string` The resolution used for time bucketing. - `Slots []map[string, unknown]` Time-bucketed result rows. Each slot contains a `time_bucket` field plus the requested stats and group-by dimensions. ### Example ```go package main import ( "context" "fmt" "time" "github.com/cloudflare/cloudflare-go" "github.com/cloudflare/cloudflare-go/option" "github.com/cloudflare/cloudflare-go/shared" ) func main() { client := cloudflare.NewClient( option.WithAPIToken("Sn3lZJTBX6kkg7OdcBUAxOO963GEIyGQqnFTOFYY"), ) response, err := client.AnalyticsQuery.Timeseries( context.TODO(), "shadow_it", cloudflare.AnalyticsQueryTimeseriesParams{ AccountID: cloudflare.F("023e105f4ecef8ad9ca31a8372d0c353"), Filters: cloudflare.F([]cloudflare.AnalyticsQueryTimeseriesParamsFilter{cloudflare.AnalyticsQueryTimeseriesParamsFilter{ Name: cloudflare.F("allowed"), Op: cloudflare.F("eq"), Values: cloudflare.F([]cloudflare.AnalyticsQueryTimeseriesParamsFiltersValueUnion{shared.UnionBool(true)}), }}), From: cloudflare.F(time.Now()), GroupBy: cloudflare.F([]string{"country", "allowed"}), Resolution: cloudflare.F("day"), Stats: cloudflare.F([]string{"attemptsTotal"}), To: cloudflare.F(time.Now()), }, ) if err != nil { panic(err.Error()) } fmt.Printf("%+v\n", response.Resolution) } ``` #### Response ```json { "errors": [], "messages": [ { "code": 1000, "message": "API in beta: expect breaking changes." } ], "result": { "resolution": "hour", "slots": [ { "appName": "Slack", "bytesTotal": 1048576, "time_bucket": "2024-11-05T00:00:00Z" }, { "appName": "Slack", "bytesTotal": 2097152, "time_bucket": "2024-11-05T01:00:00Z" } ] }, "success": true } ``` ## Query analytics top-N `client.AnalyticsQuery.TopN(ctx, dataset, params) (*SinglePage[AnalyticsQueryTopNResponse], error)` **post** `/accounts/{account_id}/analytics/query/{dataset}/top-n` Returns the top N results for a dataset by a specified stat. Includes an array of result rows, each containing the requested stats and group-by dimensions. ### Parameters - `dataset string` - `params AnalyticsQueryTopNParams` - `AccountID param.Field[string]` Path param: Cloudflare account identifier. - `Filters param.Field[[]AnalyticsQueryTopNParamsFilter]` Body param: Filters to apply before aggregating results. - `Name string` Specifies the column name to filter on. Requires a valid column for the target dataset (e.g. `country`, `allowed`, `appId`). - `Op string` Filter operator. Common values: `eq`, `neq`, `in`, `not_in`, `gt`, `lt`, `gte`, `lte`. - `Values []AnalyticsQueryTopNParamsFiltersValueUnion` Values to match against. Type depends on the column. - `UnionString` - `UnionBool` - `UnionFloat` - `From param.Field[Time]` Body param: The start of the query time range (inclusive). RFC3339 format with timezone is required (e.g. `2024-11-05T00:00:00Z`). - `GroupBy param.Field[[]string]` Body param: Specifies the column names to group results by. Requires valid columns for the target dataset. - `N param.Field[int64]` Body param: Maximum number of results to return. - `OrderBy param.Field[string]` Body param: Specifies the stat name for sorting results in descending order. Requires a valid stat for the target dataset. - `Stats param.Field[[]string]` Body param: Specifies the stat names to include in results. Requires valid stats for the target dataset (e.g. `attemptsTotal`, `bytesTotal`). - `To param.Field[Time]` Body param: Specifies the end of the query time range (exclusive). Requires RFC3339 format with timezone. ### Returns - `type AnalyticsQueryTopNResponse map[string, unknown]` Maps field names to values. Keys represent stat names and group-by column names. Values depend on the dataset (strings, numbers, booleans). ### Example ```go package main import ( "context" "fmt" "time" "github.com/cloudflare/cloudflare-go" "github.com/cloudflare/cloudflare-go/option" ) func main() { client := cloudflare.NewClient( option.WithAPIToken("Sn3lZJTBX6kkg7OdcBUAxOO963GEIyGQqnFTOFYY"), ) page, err := client.AnalyticsQuery.TopN( context.TODO(), "gateway-http", cloudflare.AnalyticsQueryTopNParams{ AccountID: cloudflare.F("023e105f4ecef8ad9ca31a8372d0c353"), Filters: cloudflare.F([]cloudflare.AnalyticsQueryTopNParamsFilter{}), From: cloudflare.F(time.Now()), GroupBy: cloudflare.F([]string{"appName", "appCategory"}), N: cloudflare.F(int64(10)), OrderBy: cloudflare.F("bytesTotal"), Stats: cloudflare.F([]string{"bytesTotal", "requestsTotal"}), To: cloudflare.F(time.Now()), }, ) if err != nil { panic(err.Error()) } fmt.Printf("%+v\n", page) } ``` #### Response ```json { "errors": [], "messages": [ { "code": 1000, "message": "API in beta: expect breaking changes." } ], "result": [ { "appCategory": "Collaboration", "appName": "Slack", "bytesTotal": 10485760, "requestsTotal": 1024 }, { "appCategory": "File Storage", "appName": "Dropbox", "bytesTotal": 5242880, "requestsTotal": 512 } ], "success": true } ``` # Data Security # Content Findings ## Top integrations by content findings `client.AnalyticsQuery.DataSecurity.ContentFindings.TopN(ctx, params) (*SinglePage[AnalyticsQueryDataSecurityContentFindingTopNResponse], error)` **post** `/accounts/{account_id}/analytics/query/data-security/content-findings/top-n` Returns the top N integrations ranked by total content findings. ### Parameters - `params AnalyticsQueryDataSecurityContentFindingTopNParams` - `AccountID param.Field[string]` Path param: Cloudflare account identifier. - `Filters param.Field[[]AnalyticsQueryDataSecurityContentFindingTopNParamsFilter]` Body param: Filters to apply. `findingType = content` is applied automatically for CASB data. - `Name string` Specifies the column name to filter on. Requires a valid column for the target dataset (e.g. `country`, `allowed`, `appId`). - `Op string` Filter operator. Common values: `eq`, `neq`, `in`, `not_in`, `gt`, `lt`, `gte`, `lte`. - `Values []AnalyticsQueryDataSecurityContentFindingTopNParamsFiltersValueUnion` Values to match against. Type depends on the column. - `UnionString` - `UnionBool` - `UnionFloat` - `From param.Field[Time]` Body param: Start of the query time range (inclusive). RFC3339. - `N param.Field[int64]` Body param: Maximum number of integrations to return. - `To param.Field[Time]` Body param: End of the query time range (exclusive). RFC3339. ### Returns - `type AnalyticsQueryDataSecurityContentFindingTopNResponse map[string, unknown]` Maps field names to values. Keys represent stat names and group-by column names. Values depend on the dataset (strings, numbers, booleans). ### Example ```go package main import ( "context" "fmt" "time" "github.com/cloudflare/cloudflare-go" "github.com/cloudflare/cloudflare-go/option" ) func main() { client := cloudflare.NewClient( option.WithAPIToken("Sn3lZJTBX6kkg7OdcBUAxOO963GEIyGQqnFTOFYY"), ) page, err := client.AnalyticsQuery.DataSecurity.ContentFindings.TopN(context.TODO(), cloudflare.AnalyticsQueryDataSecurityContentFindingTopNParams{ AccountID: cloudflare.F("023e105f4ecef8ad9ca31a8372d0c353"), Filters: cloudflare.F([]cloudflare.AnalyticsQueryDataSecurityContentFindingTopNParamsFilter{}), From: cloudflare.F(time.Now()), N: cloudflare.F(int64(10)), To: cloudflare.F(time.Now()), }) if err != nil { panic(err.Error()) } fmt.Printf("%+v\n", page) } ``` #### Response ```json { "errors": [], "messages": [ { "code": 1000, "message": "API in beta: expect breaking changes." } ], "result": [ { "integrationId": "123e4567-e89b-12d3-a456-426614174000", "integrationName": "Google Workspace", "total": 42 }, { "integrationId": "223e4567-e89b-12d3-a456-426614174001", "integrationName": "Microsoft 365", "total": 17 } ], "success": true } ``` # Findings ## Data security findings summary `client.AnalyticsQuery.DataSecurity.Findings.Summary(ctx, params) (*AnalyticsQueryDataSecurityFindingSummaryResponse, error)` **post** `/accounts/{account_id}/analytics/query/data-security/findings/summary` Returns aggregate current-period and previous-period totals for CASB findings. ### Parameters - `params AnalyticsQueryDataSecurityFindingSummaryParams` - `AccountID param.Field[string]` Path param: Cloudflare account identifier. - `Filters param.Field[[]AnalyticsQueryDataSecurityFindingSummaryParamsFilter]` Body param: Filters to apply. - `Name string` Specifies the column name to filter on. Requires a valid column for the target dataset (e.g. `country`, `allowed`, `appId`). - `Op string` Filter operator. Common values: `eq`, `neq`, `in`, `not_in`, `gt`, `lt`, `gte`, `lte`. - `Values []AnalyticsQueryDataSecurityFindingSummaryParamsFiltersValueUnion` Values to match against. Type depends on the column. - `UnionString` - `UnionBool` - `UnionFloat` - `From param.Field[Time]` Body param: Start of the query time range (inclusive). RFC3339. - `To param.Field[Time]` Body param: End of the query time range (exclusive). RFC3339. ### Returns - `type AnalyticsQueryDataSecurityFindingSummaryResponse struct{…}` - `CurrentTotal []map[string, unknown]` Aggregated stats for the requested time range. - `PreviousTotal []map[string, unknown]` Aggregated stats for the equivalent preceding time range, for trend comparison. ### Example ```go package main import ( "context" "fmt" "time" "github.com/cloudflare/cloudflare-go" "github.com/cloudflare/cloudflare-go/option" ) func main() { client := cloudflare.NewClient( option.WithAPIToken("Sn3lZJTBX6kkg7OdcBUAxOO963GEIyGQqnFTOFYY"), ) response, err := client.AnalyticsQuery.DataSecurity.Findings.Summary(context.TODO(), cloudflare.AnalyticsQueryDataSecurityFindingSummaryParams{ AccountID: cloudflare.F("023e105f4ecef8ad9ca31a8372d0c353"), Filters: cloudflare.F([]cloudflare.AnalyticsQueryDataSecurityFindingSummaryParamsFilter{}), From: cloudflare.F(time.Now()), To: cloudflare.F(time.Now()), }) if err != nil { panic(err.Error()) } fmt.Printf("%+v\n", response.CurrentTotal) } ``` #### Response ```json { "errors": [], "messages": [ { "code": 1000, "message": "API in beta: expect breaking changes." } ], "result": { "currentTotal": [ { "findingProduct": "Cloud", "findingType": "Content", "findingsTotal": 48291 }, { "findingProduct": "SaaS", "findingType": "Posture", "findingsTotal": 1205 } ], "previousTotal": [ { "findingProduct": "Cloud", "findingType": "Content", "findingsTotal": 41033 }, { "findingProduct": "SaaS", "findingType": "Posture", "findingsTotal": 982 } ] }, "success": true } ``` ## Data security findings timeseries `client.AnalyticsQuery.DataSecurity.Findings.Timeseries(ctx, params) (*AnalyticsQueryDataSecurityFindingTimeseriesResponse, error)` **post** `/accounts/{account_id}/analytics/query/data-security/findings/timeseries` Returns merged time-bucketed CASB findings. ### Parameters - `params AnalyticsQueryDataSecurityFindingTimeseriesParams` - `AccountID param.Field[string]` Path param: Cloudflare account identifier. - `Filters param.Field[[]AnalyticsQueryDataSecurityFindingTimeseriesParamsFilter]` Body param: Filters to apply. - `Name string` Specifies the column name to filter on. Requires a valid column for the target dataset (e.g. `country`, `allowed`, `appId`). - `Op string` Filter operator. Common values: `eq`, `neq`, `in`, `not_in`, `gt`, `lt`, `gte`, `lte`. - `Values []AnalyticsQueryDataSecurityFindingTimeseriesParamsFiltersValueUnion` Values to match against. Type depends on the column. - `UnionString` - `UnionBool` - `UnionFloat` - `From param.Field[Time]` Body param: Start of the query time range (inclusive). RFC3339. - `To param.Field[Time]` Body param: End of the query time range (exclusive). RFC3339. ### Returns - `type AnalyticsQueryDataSecurityFindingTimeseriesResponse struct{…}` Merged CASB and CDE findings timeseries result. - `Slots []map[string, unknown]` Contains time-bucketed result rows. Each slot includes a `timestamp` plus `content` and `posture` maps with `cloud` and `saas` keys. - `Resolution string` Always null for this endpoint. ### Example ```go package main import ( "context" "fmt" "time" "github.com/cloudflare/cloudflare-go" "github.com/cloudflare/cloudflare-go/option" ) func main() { client := cloudflare.NewClient( option.WithAPIToken("Sn3lZJTBX6kkg7OdcBUAxOO963GEIyGQqnFTOFYY"), ) response, err := client.AnalyticsQuery.DataSecurity.Findings.Timeseries(context.TODO(), cloudflare.AnalyticsQueryDataSecurityFindingTimeseriesParams{ AccountID: cloudflare.F("023e105f4ecef8ad9ca31a8372d0c353"), Filters: cloudflare.F([]cloudflare.AnalyticsQueryDataSecurityFindingTimeseriesParamsFilter{}), From: cloudflare.F(time.Now()), To: cloudflare.F(time.Now()), }) if err != nil { panic(err.Error()) } fmt.Printf("%+v\n", response.Slots) } ``` #### Response ```json { "errors": [], "messages": [ { "code": 1000, "message": "API in beta: expect breaking changes." } ], "result": { "slots": [ { "content": { "cloud": 150, "saas": 23 }, "posture": { "cloud": 0, "saas": 5 }, "timestamp": "2024-11-05T00:00:00Z" }, { "content": { "cloud": 180, "saas": 30 }, "posture": { "cloud": 0, "saas": 7 }, "timestamp": "2024-11-06T00:00:00Z" } ] }, "success": true } ```