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
  }
}