curl --request POST \
--url https://{host}/api/v3/audit-logs/export \
--header 'Content-Type: application/json' \
--header 'X-Qanapi-Authorization: <api-key>' \
--data '
{
"from": "2023-11-07T05:31:56Z",
"to": "2023-11-07T05:31:56Z",
"action": "<string>",
"container_id": "<string>",
"principal_id": "<string>",
"principal_type": "<string>",
"status": "<string>",
"request_id": "<string>",
"instance_id": "<string>",
"format": "jsonl",
"gzip": false,
"purge": false
}
'import requests
url = "https://{host}/api/v3/audit-logs/export"
payload = {
"from": "2023-11-07T05:31:56Z",
"to": "2023-11-07T05:31:56Z",
"action": "<string>",
"container_id": "<string>",
"principal_id": "<string>",
"principal_type": "<string>",
"status": "<string>",
"request_id": "<string>",
"instance_id": "<string>",
"format": "jsonl",
"gzip": False,
"purge": False
}
headers = {
"X-Qanapi-Authorization": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-Qanapi-Authorization': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
from: '2023-11-07T05:31:56Z',
to: '2023-11-07T05:31:56Z',
action: '<string>',
container_id: '<string>',
principal_id: '<string>',
principal_type: '<string>',
status: '<string>',
request_id: '<string>',
instance_id: '<string>',
format: 'jsonl',
gzip: false,
purge: false
})
};
fetch('https://{host}/api/v3/audit-logs/export', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://{host}/api/v3/audit-logs/export",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'from' => '2023-11-07T05:31:56Z',
'to' => '2023-11-07T05:31:56Z',
'action' => '<string>',
'container_id' => '<string>',
'principal_id' => '<string>',
'principal_type' => '<string>',
'status' => '<string>',
'request_id' => '<string>',
'instance_id' => '<string>',
'format' => 'jsonl',
'gzip' => false,
'purge' => false
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-Qanapi-Authorization: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://{host}/api/v3/audit-logs/export"
payload := strings.NewReader("{\n \"from\": \"2023-11-07T05:31:56Z\",\n \"to\": \"2023-11-07T05:31:56Z\",\n \"action\": \"<string>\",\n \"container_id\": \"<string>\",\n \"principal_id\": \"<string>\",\n \"principal_type\": \"<string>\",\n \"status\": \"<string>\",\n \"request_id\": \"<string>\",\n \"instance_id\": \"<string>\",\n \"format\": \"jsonl\",\n \"gzip\": false,\n \"purge\": false\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-Qanapi-Authorization", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://{host}/api/v3/audit-logs/export")
.header("X-Qanapi-Authorization", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"from\": \"2023-11-07T05:31:56Z\",\n \"to\": \"2023-11-07T05:31:56Z\",\n \"action\": \"<string>\",\n \"container_id\": \"<string>\",\n \"principal_id\": \"<string>\",\n \"principal_type\": \"<string>\",\n \"status\": \"<string>\",\n \"request_id\": \"<string>\",\n \"instance_id\": \"<string>\",\n \"format\": \"jsonl\",\n \"gzip\": false,\n \"purge\": false\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://{host}/api/v3/audit-logs/export")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-Qanapi-Authorization"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"from\": \"2023-11-07T05:31:56Z\",\n \"to\": \"2023-11-07T05:31:56Z\",\n \"action\": \"<string>\",\n \"container_id\": \"<string>\",\n \"principal_id\": \"<string>\",\n \"principal_type\": \"<string>\",\n \"status\": \"<string>\",\n \"request_id\": \"<string>\",\n \"instance_id\": \"<string>\",\n \"format\": \"jsonl\",\n \"gzip\": false,\n \"purge\": false\n}"
response = http.request(request)
puts response.read_body"<string>"{
"message": "Unauthorized.",
"error": "InvalidApiKeyException"
}{
"message": "Unauthorized.",
"error": "InvalidApiKeyException",
"errors": {
"type": [
"The type field is required."
],
"configuration_ids": [
"No configuration has the id `...`."
]
}
}Export/purge audit logs
Streams matching records as JSONL or CSV, optionally gzipped. With
purge set, the exported records are deleted in the same transaction
that read them, so nothing can be purged that was not successfully
exported.
A purge is itself recorded, with the window it covered, so a later chain
verification can tell an authorised purge apart from tampering. Requires
audit:export, and audit:purge as well when purging.
curl --request POST \
--url https://{host}/api/v3/audit-logs/export \
--header 'Content-Type: application/json' \
--header 'X-Qanapi-Authorization: <api-key>' \
--data '
{
"from": "2023-11-07T05:31:56Z",
"to": "2023-11-07T05:31:56Z",
"action": "<string>",
"container_id": "<string>",
"principal_id": "<string>",
"principal_type": "<string>",
"status": "<string>",
"request_id": "<string>",
"instance_id": "<string>",
"format": "jsonl",
"gzip": false,
"purge": false
}
'import requests
url = "https://{host}/api/v3/audit-logs/export"
payload = {
"from": "2023-11-07T05:31:56Z",
"to": "2023-11-07T05:31:56Z",
"action": "<string>",
"container_id": "<string>",
"principal_id": "<string>",
"principal_type": "<string>",
"status": "<string>",
"request_id": "<string>",
"instance_id": "<string>",
"format": "jsonl",
"gzip": False,
"purge": False
}
headers = {
"X-Qanapi-Authorization": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-Qanapi-Authorization': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
from: '2023-11-07T05:31:56Z',
to: '2023-11-07T05:31:56Z',
action: '<string>',
container_id: '<string>',
principal_id: '<string>',
principal_type: '<string>',
status: '<string>',
request_id: '<string>',
instance_id: '<string>',
format: 'jsonl',
gzip: false,
purge: false
})
};
fetch('https://{host}/api/v3/audit-logs/export', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://{host}/api/v3/audit-logs/export",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'from' => '2023-11-07T05:31:56Z',
'to' => '2023-11-07T05:31:56Z',
'action' => '<string>',
'container_id' => '<string>',
'principal_id' => '<string>',
'principal_type' => '<string>',
'status' => '<string>',
'request_id' => '<string>',
'instance_id' => '<string>',
'format' => 'jsonl',
'gzip' => false,
'purge' => false
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-Qanapi-Authorization: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://{host}/api/v3/audit-logs/export"
payload := strings.NewReader("{\n \"from\": \"2023-11-07T05:31:56Z\",\n \"to\": \"2023-11-07T05:31:56Z\",\n \"action\": \"<string>\",\n \"container_id\": \"<string>\",\n \"principal_id\": \"<string>\",\n \"principal_type\": \"<string>\",\n \"status\": \"<string>\",\n \"request_id\": \"<string>\",\n \"instance_id\": \"<string>\",\n \"format\": \"jsonl\",\n \"gzip\": false,\n \"purge\": false\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-Qanapi-Authorization", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://{host}/api/v3/audit-logs/export")
.header("X-Qanapi-Authorization", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"from\": \"2023-11-07T05:31:56Z\",\n \"to\": \"2023-11-07T05:31:56Z\",\n \"action\": \"<string>\",\n \"container_id\": \"<string>\",\n \"principal_id\": \"<string>\",\n \"principal_type\": \"<string>\",\n \"status\": \"<string>\",\n \"request_id\": \"<string>\",\n \"instance_id\": \"<string>\",\n \"format\": \"jsonl\",\n \"gzip\": false,\n \"purge\": false\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://{host}/api/v3/audit-logs/export")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-Qanapi-Authorization"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"from\": \"2023-11-07T05:31:56Z\",\n \"to\": \"2023-11-07T05:31:56Z\",\n \"action\": \"<string>\",\n \"container_id\": \"<string>\",\n \"principal_id\": \"<string>\",\n \"principal_type\": \"<string>\",\n \"status\": \"<string>\",\n \"request_id\": \"<string>\",\n \"instance_id\": \"<string>\",\n \"format\": \"jsonl\",\n \"gzip\": false,\n \"purge\": false\n}"
response = http.request(request)
puts response.read_body"<string>"{
"message": "Unauthorized.",
"error": "InvalidApiKeyException"
}{
"message": "Unauthorized.",
"error": "InvalidApiKeyException",
"errors": {
"type": [
"The type field is required."
],
"configuration_ids": [
"No configuration has the id `...`."
]
}
}Authorizations
A machine credential, qk_ followed by its secret. The first twelve
characters are an indexed prefix; the rest is compared in constant time
against a stored SHA-256 hash. A key reaches only the configurations it is
linked to.
It may also be sent as Authorization: Bearer qk_..., which is
recognised by the prefix.
Body
Accepts every filter the query endpoint accepts, plus these.
jsonl, csv Delete the exported records in the same transaction that read them,
so nothing is purged that was not successfully exported. Requires
audit:purge, and is itself recorded with the window it covered.
Response
The export stream.
The response is of type string.