Query data via Axiom API
Learn how to use Axiom querying API to create and get query objects.
Use Axiom querying API to create and get query objects.
Authorization and Headers
The only expected headers are the Authorization: Bearer
, which is your API or Personal Token. Learn more about API Token and Org ID.
Using Axiom Node.js library to query data
Axiom maintains the axiom-js to provide official Node.js bindings for the Axiom API.
Install using npm install
:
npm install @axiomhq/js
If you use the Axiom CLI, run eval $(axiom config export -f)
to configure your environment variables.
Otherwise create a personal token in the Axiom settings and export it as AXIOM_TOKEN
. Set AXIOM_ORG_ID
to the organization ID from the settings page of the organization you want to access.
Create and use a client like this:
// The purpose of this example is to show how to query a dataset using the Axiom
// Processing Language (APL).
import { Axiom } from '@axiomhq/js';
const axiom = new Axiom({
token: process.env.AXIOM_TOKEN,
orgId: process.env.AXIOM_ORG_ID,
});
async function query() {
const aplQuery = "['flights'] | where altitude > 49000 and flight != '' ";
const res = await axiom.query(aplQuery);
if (!res.matches || res.matches.length === 0) {
console.warn('no matches found');
return;
}
for (let matched of res.matches) {
console.log(matched.data);
}
}
query();
In the above example we’re querying a dataset containing contemporary flight data obtained from an ADSB antenna. Results may look similar to this:
{
aircraft: null,
altitude: 123600,
category: null,
flight: 'BCI96D ',
hex: '407241',
lat: 50.951285,
lon: -1.347961,
messages: 13325,
mlat: [ 'lat', 'lon', 'track', 'speed', 'vert_rate' ],
now: null,
nucp: 0,
rssi: -13.3,
seen: 3.6,
seen_pos: 19.7,
speed: 260,
squawk: '6014',
tisb: [],
track: 197,
type: null,
vert_rate: 64
}
{
aircraft: null,
altitude: 123600,
category: null,
flight: 'BCI96D ',
hex: '407241',
lat: 50.951285,
lon: -1.347961,
messages: 13325,
mlat: [ 'lat', 'lon', 'track', 'speed', 'vert_rate' ],
now: null,
nucp: 0,
rssi: -13.3,
seen: 4.6,
seen_pos: 20.8,
speed: 260,
squawk: '6014',
tisb: [],
track: 197,
type: null,
vert_rate: 64
}
Further examples can be found in the axiom-js repo.
Querying via Curl using APL
This section provides a guide on how to leverage the power of APL through curl commands. By combining the flexibility of curl with the querying capabilities of APL, users can seamlessly fetch and analyze their data right from the terminal.
Whether you’re looking to fetch specific data points, aggregate metrics over time, or filter datasets based on certain criteria, the examples provided here will serve as a foundation to build upon. As you become more familiar with APL’s syntax and curl’s options, you’ll find that the possibilities are vast and the insights you can derive are profound.
Examples
Count of distinct routes
curl -X 'POST' 'https://api.axiom.co/v1/datasets/_apl?format=tabular' \
-H 'Authorization: Bearer $API_TOKEN' \
-H 'Accept: application/json' \
-H 'Accept-Encoding: gzip' \
-H 'Content-Type: application/json' \
-d '{
"apl": "vercel | summarize Count = dcount(vercel.route)",
"startTime": "2023-08-15T00:00:00Z",
"endTime": "2023-08-22T00:00:00Z"
}'
Top 5 routes by count
curl -X 'POST' 'https://api.axiom.co/v1/datasets/_apl?format=tabular' \
-H 'Authorization: Bearer $API_TOKEN' \
-H 'Accept: application/json' \
-H 'Accept-Encoding: gzip' \
-H 'Content-Type: application/json' \
-d '{
"apl": "vercel | summarize Count = dcount(vercel.route)",
"startTime": "2023-08-15T00:00:00Z",
"endTime": "2023-08-22T00:00:00Z"
}'
Average request duration
curl -X 'POST' 'https://api.axiom.co/v1/datasets/_apl?format=tabular' \
-H 'Authorization: Bearer $API_TOKEN' \
-H 'Accept: application/json' \
-H 'Accept-Encoding: gzip' \
-H 'Content-Type: application/json' \
-d '{
"apl": "vercel | summarize AvgDuration = avg(vercel.duration)",
"startTime": "2023-08-15T00:00:00Z",
"endTime": "2023-08-22T00:00:00Z"
}'
Requests with duration greater than 1 second
curl -X 'POST' 'https://api.axiom.co/v1/datasets/_apl?format=tabular' \
-H 'Authorization: Bearer $API_TOKEN' \
-H 'Accept: application/json' \
-H 'Accept-Encoding: gzip' \
-H 'Content-Type: application/json' \
-d '{
"apl": "vercel | where vercel.duration > 1000",
"startTime": "2023-08-15T00:00:00Z",
"endTime": "2023-08-22T00:00:00Z"
}'
Top 3 routes with the highest average duration
curl -X 'POST' 'https://api.axiom.co/v1/datasets/_apl?format=tabular' \
-H 'Authorization: Bearer $API_TOKEN' \
-H 'Accept: application/json' \
-H 'Accept-Encoding: gzip' \
-H 'Content-Type: application/json' \
-d '{
"apl": "vercel | summarize AvgDuration = avg(vercel.duration) by vercel.route | top 3 by AvgDuration desc",
"startTime": "2023-08-15T00:00:00Z",
"endTime": "2023-08-22T00:00:00Z"
}'
Requests grouped by hour
curl -X 'POST' 'https://api.axiom.co/v1/datasets/_apl?format=tabular' \
-H 'Authorization: Bearer $API_TOKEN' \
-H 'Accept: application/json' \
-H 'Accept-Encoding: gzip' \
-H 'Content-Type: application/json' \
-d '{
"apl": "vercel | summarize Count = count() by bin(_time, 1h)",
"startTime": "2023-08-15T00:00:00Z",
"endTime": "2023-08-22T00:00:00Z"
}'
Requests with errors
curl -X 'POST' 'https://api.axiom.co/v1/datasets/_apl?format=tabular' \
-H 'Authorization: Bearer $API_TOKEN' \
-H 'Accept: application/json' \
-H 'Accept-Encoding: gzip' \
-H 'Content-Type: application/json' \
-d '{
"apl": "vercel | where vercel.status >= 400",
"startTime": "2023-08-15T00:00:00Z",
"endTime": "2023-08-22T00:00:00Z"
}'
Getting the most common user agents
curl -X 'POST' 'https://api.axiom.co/v1/datasets/_apl?format=tabular' \
-H 'Authorization: Bearer $API_TOKEN' \
-H 'Accept: application/json' \
-H 'Accept-Encoding: gzip' \
-H 'Content-Type: application/json' \
-d '{
"apl": "sample-http-logs | summarize count() by user_agent | top 5 by count()",
"startTime": "2023-08-15T00:00:00Z",
"endTime": "2023-08-22T00:00:00Z"
}'
Identifying the server data centers with the highest number of requests
curl -X 'POST' 'https://api.axiom.co/v1/datasets/_apl?format=tabular' \
-H 'Authorization: Bearer $API_TOKEN' \
-H 'Accept: application/json' \
-H 'Accept-Encoding: gzip' \
-H 'Content-Type: application/json' \
-d '{
"apl": "sample-http-logs | summarize count() by server_datacenter | top 3 by count()",
"startTime": "2023-08-15T00:00:00Z",
"endTime": "2023-08-22T00:00:00Z"
}'
Identifying the average, minimum, and maximum request duration for each method type
curl -X 'POST' 'https://api.axiom.co/v1/datasets/_apl?format=tabular' \
-H 'Authorization: Bearer $API_TOKEN' \
-H 'Accept: application/json' \
-H 'Accept-Encoding: gzip' \
-H 'Content-Type: application/json' \
-d '{
"apl": "sample-http-logs | summarize avg(todouble(req_duration_ms)), min(todouble(req_duration_ms)), max(todouble(req_duration_ms)) by method",
"startTime": "2023-08-15T00:00:00Z",
"endTime": "2023-08-22T00:00:00Z"
}'
Finding the top 3 URIs accessed via TLS connections with a response body size greater than a specified threshold
curl -X 'POST' 'https://api.axiom.co/v1/datasets/_apl?format=tabular' \
-H 'Authorization: Bearer $API_TOKEN' \
-H 'Accept: application/json' \
-H 'Accept-Encoding: gzip' \
-H 'Content-Type: application/json' \
-d '{
"apl": "sample-http-logs | where is_tls == true and todouble(resp_body_size_bytes) > 5000 | summarize count() by uri | top 3 by count()",
"startTime": "2023-08-15T00:00:00Z",
"endTime": "2023-08-22T00:00:00Z"
}'
Calculating the 95th percentile of the request duration for each server datacenter
curl -X 'POST' 'https://api.axiom.co/v1/datasets/_apl?format=tabular' \
-H 'Authorization: Bearer $API_TOKEN' \
-H 'Accept: application/json' \
-H 'Accept-Encoding: gzip' \
-H 'Content-Type: application/json' \
-d '{
"apl": "sample-http-logs | summarize percentile(todouble(req_duration_ms), 95) by server_datacenter",
"startTime": "2023-08-15T00:00:00Z",
"endTime": "2023-08-22T00:00:00Z"
}'
Active issue contributors
curl -X 'POST' 'https://api.axiom.co/v1/datasets/_apl?format=tabular' \
-H 'Authorization: Bearer $API_TOKEN' \
-H 'Accept: application/json' \
-H 'Accept-Encoding: gzip' \
-H 'Content-Type: application/json' \
-d '{
"apl": "github-issue-comment-event | where repo startswith \"kubernetes/\" | where actor !endswith \"[bot]\" | summarize dcount(actor) by bin_auto(_time)",
"startTime": "2023-08-15T00:00:00Z",
"endTime": "2023-08-22T00:00:00Z"
}'
Top Issue Wranglers
curl -X 'POST' 'https://api.axiom.co/v1/datasets/_apl?format=tabular' \
-H 'Authorization: Bearer $API_TOKEN' \
-H 'Accept: application/json' \
-H 'Accept-Encoding: gzip' \
-H 'Content-Type: application/json' \
-d '{
"apl": "github-issues-event | where (actor !endswith \"[bot]\" and repo startswith \"cockroachdb/\" and actor !~ \"cockroach-teamcity\") | summarize topk(actor, 5) by bin_auto(_time), action",
"startTime": "2023-08-15T00:00:00Z",
"endTime": "2023-08-22T00:00:00Z"
}'
Using Curl to query the API
POST api.axiom.co/v1/datasets/\{id\}/query
curl -X 'POST' \
'https://api.axiom.co/v1/datasets/<dataset_id>/query?saveAsKind=<save_as_kind_query>&streaming-duration=<streaming_duration>&nocache=true' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer <$API_TOKEN>' \
-d '{
"aggregations": [
{
"alias": "string",
"argument": {},
"field": "string",
"op": "count"
}
],
"continuationToken": "string",
"cursor": "string",
"endTime": "string",
"filter": {
"caseSensitive": true,
"children": [
"string"
],
"field": "string",
"op": "and",
"value": {}
},
"groupBy": [
"string"
],
"includeCursor": true,
"limit": 0,
"order": [
{
"desc": true,
"field": "string"
}
],
"project": [
{
"alias": "string",
"field": "string"
}
],
"queryOptions": {
"against": "string",
"againstStart": "string",
"againstTimestamp": "string",
"caseSensitive": "string",
"containsTimeFilter": "string",
"datasets": "string",
"displayNull": "string",
"editorContent": "string",
"endColumn": "string",
"endLineNumber": "string",
"endTime": "string",
"integrationsFilter": "string",
"openIntervals": "string",
"quickRange": "string",
"resolution": "string",
"startColumn": "string",
"startLineNumber": "string",
"startTime": "string",
"timeSeriesView": "string"
},
"resolution": "string",
"startTime": "string",
"virtualFields": [
{
"alias": "string",
"expr": "string"
}
]
}'
Response Example
Response code 200 and the response body:
{
"buckets": {
"series": [
{
"endTime": "2022-07-26T03:00:48.925Z",
"groups": [
{
"aggregations": [
{
"op": "string",
"value": {}
}
],
"group": {
"additionalProp1": {},
"additionalProp2": {},
"additionalProp3": {}
},
"id": 0
}
],
"startTime": "2022-07-26T03:00:48.925Z"
}
],
"totals": [
{
"aggregations": [
{
"op": "string",
"value": {}
}
],
"group": {
"additionalProp1": {},
"additionalProp2": {},
"additionalProp3": {}
},
"id": 0
}
]
},
"fieldsMeta": [
{
"description": "string",
"hidden": true,
"name": "string",
"type": "string",
"unit": "string"
}
],
"matches": [
{
"_rowId": "string",
"_sysTime": "2022-07-26T03:00:48.925Z",
"_time": "2022-07-26T03:00:48.925Z",
"data": {
"additionalProp1": {},
"additionalProp2": {},
"additionalProp3": {}
}
}
],
"status": {
"blocksExamined": 0,
"cacheStatus": 0,
"continuationToken": "string",
"elapsedTime": 0,
"isEstimate": true,
"isPartial": true,
"maxBlockTime": "2022-07-26T03:00:48.925Z",
"messages": [
{
"code": "string",
"count": 0,
"msg": "string",
"priority": "string"
}
],
"minBlockTime": "2022-07-26T03:00:48.925Z",
"numGroups": 0,
"rowsExamined": 0,
"rowsMatched": 0
}
}
Was this page helpful?