Use Axiom querying API to create and get query objects.
Authorization and headers
The only expected header is Authorization: Bearer
which is your token to authenticate the request. For more information, see Tokens.
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
:
If you use the Axiom CLI, run eval $(axiom config export -f)
to configure your environment variables.
Otherwise, create an API token and export it as AXIOM_TOKEN
.
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
});
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
}
}