Querying API Traffic Analytics

Breakdown of the apiTrafficAnalytics operation available on Platform API.

Summary

The GraphQL Platform API exposes a useful operation (apiTrafficAnalytics) for analyzing API call volume, errors, and latency. It allows you to filter and group the data by multiple dimensions such as time, API, consumer, and much more.

The results are returned in a flat object that can easily be transformed into input for charting or pivot tables, in this document we will explore both scenarios.

How to use

In order to only filter data by time you would use the "fromDate" and "toDate" fields. The "resolution" field in mandatory, so in order to get a single calculation for the entire period, make sure the resolution is larger than the date range.

The example query below demonstrates how to query all APIs for a week, and get all metrics as a response.

{
  "data": {
    "apiTrafficAnalytics": [
      {
        "date": "2022-01-01T00:00:00.000Z",
        "requests": 556238851,
        "latency": 1066.0081135379016,
        "errors": 14139965
      }
    ]
  }
}
{
	"query": "query apiTrafficAnalytics($where:AnalyticsStatsInput!){
  	apiTrafficAnalytics(where:$where){
      date
      requests 
      latency
      errors
    }}",
	"variables": {
		"where": {
			"fromDate": "2022-12-04",
			"toDate": "2022-12-11",
			"resolution": "YEARS"
		}
	}
}

Now let's try adding the "API" dimension to this request. This will return the results for each API, instead of a single aggregated number. In order to actually be able to tell which array value belongs to which API, we have to also ask to get that in the response. Finally, we want to narrow the results to only 3 APIs, we can do that by adding their Ids as an array to "apiIds". The result is the query and response below:

{
  "data": {
    "apiTrafficAnalytics": [
      {
        "date": "2022-01-01T00:00:00.000Z",
        "requests": 244642,
        "latency": 686.4737657475005,
        "errors": 91,
        "apiId": "api_41a82ace-895f-4562-b52f-c50169e370"
      },
      {
        "date": "2022-01-01T00:00:00.000Z",
        "requests": 6808,
        "latency": 991.5174794359577,
        "errors": 86,
        "apiId": "api_0c5fde8c-edf3-44b2-b877-819108bf88"
      },
      {
        "date": "2022-01-01T00:00:00.000Z",
        "requests": 20520,
        "latency": 318.3720760233918,
        "errors": 254,
        "apiId": "api_a2b7c737-9e49-4a6f-95ef-e39956dff2"
      }
    ]
  }
}
{
	"query": "query apiTrafficAnalytics($where:AnalyticsStatsInput!){
  	apiTrafficAnalytics(where:$where){
      date
      requests 
      latency
      errors
    	apiId
    }}",
	"variables": {
		"where": {
			"fromDate": "2022-12-04",
			"toDate": "2022-12-11",
			"resolution": "YEARS",
    	"apiIds": [
				"api_41a82ace-895f-4562-b52f-c50169e370",
				"api_a2b7c737-9e49-4a6f-95ef-e39956dff2",
				"api_0c5fde8c-edf3-44b2-b877-819108bf88"
			]
		}
	}
}

If you were to plot this result as a bar chart, it would look something like this:

We can use the same endpoint to calculate trends in a very flexible manner. For example, let's adjust the query above in order to analyze the API traffic for each of these APIs, for each day, in order to get an better understanding of their trend. First, we should remove the redundant metrics (errors and latency). Next, we need to adjust the resolution from "YEARS" to "DAYS", given that we query a week of data, I would expect 7 results for each API. The response will be a flat list of all data, using a simple tool like this I can convert it to CSV and run a simple transpose in excel. Here is an example of the request and response:

date,api_0c5fde8c-edf3-44b2-b877-819108bf88,api_41a82ace-895f-4562-b52f-c50169e370,api_a2b7c737-9e49-4a6f-95ef-e39956dff2
2022-12-04T00:00:00.000Z,847,25614,2654
2022-12-05T00:00:00.000Z,884,27691,3152
2022-12-06T00:00:00.000Z,1012,32879,3445
2022-12-07T00:00:00.000Z,1033,29956,2342
2022-12-08T00:00:00.000Z,1298,31880,2484
2022-12-09T00:00:00.000Z,897,32270,1697
2022-12-10T00:00:00.000Z,486,40837,2812
2022-12-11T00:00:00.000Z,351,23515,1934
{
  "data": {
    "apiTrafficAnalytics": [
      {
        "date": "2022-12-04T00:00:00.000Z",
        "requests": 2654,
        "latency": 274.0097965335343,
        "errors": 9,
        "apiId": "api_a2b7c737-9e49-4a6f-95ef-e39956dff2"
      },
      {
        "date": "2022-12-04T00:00:00.000Z",
        "requests": 847,
        "latency": 3732.099173553719,
        "errors": 12,
        "apiId": "api_0c5fde8c-edf3-44b2-b877-819108bf88"
      },
      {
        "date": "2022-12-04T00:00:00.000Z",
        "requests": 25614,
        "latency": 669.6271179823534,
        "errors": 1,
        "apiId": "api_41a82ace-895f-4562-b52f-c50169e370"
      },
      {
        "date": "2022-12-05T00:00:00.000Z",
        "requests": 884,
        "latency": 343.1165158371041,
        "errors": 5,
        "apiId": "api_0c5fde8c-edf3-44b2-b877-819108bf88"
      },
      {
        "date": "2022-12-05T00:00:00.000Z",
        "requests": 27691,
        "latency": 680.3057311039688,
        "errors": 10,
        "apiId": "api_41a82ace-895f-4562-b52f-c50169e370"
      },
      {
        "date": "2022-12-05T00:00:00.000Z",
        "requests": 3152,
        "latency": 342.35659898477155,
        "errors": 8,
        "apiId": "api_a2b7c737-9e49-4a6f-95ef-e39956dff2"
      },
      {
        "date": "2022-12-06T00:00:00.000Z",
        "requests": 1012,
        "latency": 647.3330039525691,
        "errors": 12,
        "apiId": "api_0c5fde8c-edf3-44b2-b877-819108bf88"
      },
      {
        "date": "2022-12-06T00:00:00.000Z",
        "requests": 3445,
        "latency": 303.84412191582004,
        "errors": 11,
        "apiId": "api_a2b7c737-9e49-4a6f-95ef-e39956dff2"
      },
      {
        "date": "2022-12-06T00:00:00.000Z",
        "requests": 32879,
        "latency": 683.3744031144499,
        "errors": 8,
        "apiId": "api_41a82ace-895f-4562-b52f-c50169e370"
      },
      {
        "date": "2022-12-07T00:00:00.000Z",
        "requests": 29956,
        "latency": 678.8020096141007,
        "errors": 20,
        "apiId": "api_41a82ace-895f-4562-b52f-c50169e370"
      },
      {
        "date": "2022-12-07T00:00:00.000Z",
        "requests": 1033,
        "latency": 438.1490803484995,
        "errors": 9,
        "apiId": "api_0c5fde8c-edf3-44b2-b877-819108bf88"
      },
      {
        "date": "2022-12-07T00:00:00.000Z",
        "requests": 2342,
        "latency": 324.3654995730145,
        "errors": 41,
        "apiId": "api_a2b7c737-9e49-4a6f-95ef-e39956dff2"
      },
      {
        "date": "2022-12-08T00:00:00.000Z",
        "requests": 2484,
        "latency": 370.09863123993557,
        "errors": 73,
        "apiId": "api_a2b7c737-9e49-4a6f-95ef-e39956dff2"
      },
      {
        "date": "2022-12-08T00:00:00.000Z",
        "requests": 31880,
        "latency": 693.655426599749,
        "errors": 16,
        "apiId": "api_41a82ace-895f-4562-b52f-c50169e370"
      },
      {
        "date": "2022-12-08T00:00:00.000Z",
        "requests": 1298,
        "latency": 932.9352850539291,
        "errors": 23,
        "apiId": "api_0c5fde8c-edf3-44b2-b877-819108bf88"
      },
      {
        "date": "2022-12-09T00:00:00.000Z",
        "requests": 1697,
        "latency": 352.7495580436064,
        "errors": 5,
        "apiId": "api_a2b7c737-9e49-4a6f-95ef-e39956dff2"
      },
      {
        "date": "2022-12-09T00:00:00.000Z",
        "requests": 897,
        "latency": 468.1404682274248,
        "errors": 7,
        "apiId": "api_0c5fde8c-edf3-44b2-b877-819108bf88"
      },
      {
        "date": "2022-12-09T00:00:00.000Z",
        "requests": 32270,
        "latency": 737.7004648280137,
        "errors": 17,
        "apiId": "api_41a82ace-895f-4562-b52f-c50169e370"
      },
      {
        "date": "2022-12-10T00:00:00.000Z",
        "requests": 486,
        "latency": 422.66460905349794,
        "errors": 10,
        "apiId": "api_0c5fde8c-edf3-44b2-b877-819108bf88"
      },
      {
        "date": "2022-12-10T00:00:00.000Z",
        "requests": 2812,
        "latency": 295.92603129445234,
        "errors": 39,
        "apiId": "api_a2b7c737-9e49-4a6f-95ef-e39956dff2"
      },
      {
        "date": "2022-12-10T00:00:00.000Z",
        "requests": 40837,
        "latency": 670.9999510248059,
        "errors": 17,
        "apiId": "api_41a82ace-895f-4562-b52f-c50169e370"
      },
      {
        "date": "2022-12-11T00:00:00.000Z",
        "requests": 351,
        "latency": 973.9373219373219,
        "errors": 8,
        "apiId": "api_0c5fde8c-edf3-44b2-b877-819108bf88"
      },
      {
        "date": "2022-12-11T00:00:00.000Z",
        "requests": 23515,
        "latency": 673.0310865405061,
        "errors": 2,
        "apiId": "api_41a82ace-895f-4562-b52f-c50169e370"
      },
      {
        "date": "2022-12-11T00:00:00.000Z",
        "requests": 1934,
        "latency": 294.81540847983456,
        "errors": 68,
        "apiId": "api_a2b7c737-9e49-4a6f-95ef-e39956dff2"
      }
    ]
  }
}
{
	"query": "query apiTrafficAnalytics($where:AnalyticsStatsInput!){
  	apiTrafficAnalytics(where:$where){
      date
      requests 
    	apiId
    }}",
	"variables": {
		"where": {
			"fromDate": "2022-12-04",
			"toDate": "2022-12-11",
			"resolution": "DAYS",
    	"apiIds": [
				"api_41a82ace-895f-4562-b52f-c50169e370",
				"api_a2b7c737-9e49-4a6f-95ef-e39956dff2",
				"api_0c5fde8c-edf3-44b2-b877-819108bf88"
			]
		}
	}
}

We can now plot this data and create a multi-series line chart.

That's pretty amazing, but it can get much much more awesome. Let's consider an artificially complex scenario, and go through how we could implement that by exporting the raw data and creating a google sheets pivot table. We want to review the method in which we visualize the maximum latency for each project (application) on each API on a daily basis for a given week! Ewww.

Let's first create our query and add the needed dimensions API, Project and Date to the "response parameters" and "group by" filter input. We will use the same date range and APIs used in the previous example. We can see the request below but did not add the response as it is over 1700 items long.

{
	"query": "query apiTrafficAnalytics($where:AnalyticsStatsInput!){apiTrafficAnalytics(where:$where){date requests latency errors apiId appMashapeId}}",
	"variables": {
		"where": {
			"fromDate": "2022-12-04",
			"toDate": "2022-12-11T15:24:17.689Z",
			"resolution": "DAYS",
			"groupBy": [
				"API",
				"APP"
			],
			"apiIds": [
				"api_41a82ace-895f-4562-b52f-c50169e370",
				"api_a2b7c737-9e49-4a6f-95ef-e39956dff2",
				"api_0c5fde8c-edf3-44b2-b877-819108bf88"
			]
		}
	}
}

We can convert converted the result to CSV rows using this tool. Once it is in google sheets as raw row data we can create a pivot table and set it up as follows. I also added a formatting rule to highlight all cells that have a value of over 1 second.

As one can see, this API is extremely powerful and can return results in various shapes and forms.

Available Filters

Through the were object we can filter the results based on

  • Time
  • API IDs

Available Dimensions

These are the current dimensions you can use to group by. Don't forget to add the dimension as a result parameter, or else you might mistake objects for being duplicates.

NameTypeExamples
apiIds[string][]
fromDatestring"2022-12-11", "2022-12-11T15:24:17.689Z"
toDatestring"2022-12-11", "2022-12-11T15:24:17.689Z"
resolutionENUMSECONDS, MINUTES, HOURS, DAYS, MONTHS, YEARS
groupByENUMAPI, ENDPOINT, ENDPOINT_HASH, APP, API_VERSION, DATE